Re: [PATCH] x86: split e820 reserved entries record to late v2

From: Yinghai Lu
Date: Fri Aug 29 2008 - 01:06:41 EST


On Thu, Aug 28, 2008 at 8:59 PM, David Witbrodt <dawitbro@xxxxxxxxxxxxx> wrote:

>
> ===== SHELL OUTPUT (for sanity) =====
> commit e3fc96d5aca609bcf6ab0327850a109df65c1dbb
> Merge: 6b8c836... a36d241...
> Author: Ingo Molnar <mingo@xxxxxxx>
> Date: Thu Aug 28 22:57:20 2008 +0200
>
> Merge branch 'x86/core'
> =====================================
>
> Results: both ECS AMD690GM-M2 machines boot fine...
>
> - no need for "hpet=disable"
> - no error messages in 'dmesg' (except that annoying TSC b.s.)
>

please hang a while, there is some merging problem with current tip/master.

one or two hours later ingo may fix it.

or please try attached two patches....

YH
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 523d6c5..291e6cd 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1271,15 +1271,13 @@ static inline const char *e820_type_to_string(int e820_type)
/*
* Mark e820 reserved areas as busy for the resource manager.
*/
-struct resource __initdata *e820_res;
void __init e820_reserve_resources(void)
{
int i;
- u64 end;
struct resource *res;
+ u64 end;

res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
- e820_res = res;
for (i = 0; i < e820.nr_map; i++) {
end = e820.map[i].addr + e820.map[i].size - 1;
#ifndef CONFIG_RESOURCES_64BIT
@@ -1293,8 +1291,7 @@ void __init e820_reserve_resources(void)
res->end = end;

res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20))
- insert_resource(&iomem_resource, res);
+ insert_resource(&iomem_resource, res);
res++;
}

@@ -1306,19 +1303,6 @@ void __init e820_reserve_resources(void)
}
}

-void __init e820_reserve_resources_late(void)
-{
- int i;
- struct resource *res;
-
- res = e820_res;
- for (i = 0; i < e820.nr_map; i++) {
- if (e820.map[i].type == E820_RESERVED && res->start >= (1ULL<<20))
- insert_resource(&iomem_resource, res);
- res++;
- }
-}
-
char *__init default_machine_specific_memory_setup(void)
{
char *who = "BIOS-e820";
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 718fd77..5807d1b 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -31,12 +31,8 @@
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
-#include <linux/acpi.h>

#include <asm/pat.h>
-#include <asm/hpet.h>
-#include <asm/io_apic.h>
-#include <asm/e820.h>

#include "pci.h"

@@ -81,77 +77,6 @@ pcibios_align_resource(void *data, struct resource *res,
}
EXPORT_SYMBOL(pcibios_align_resource);

-static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
-{
- unsigned long base;
- unsigned long size;
- int i;
-
- base = res->start;
- size = (res->start == 0 && res->end == res->start) ? 0 :
- (res->end - res->start + 1);
-
- if (!base || !size)
- return 0;
-
-#ifdef CONFIG_HPET_TIMER
- /* for hpet */
- if (base == hpet_address && (res->flags & IORESOURCE_MEM)) {
- dev_info(&dev->dev, "BAR has HPET at %08lx-%08lx\n",
- base, base + size - 1);
- return 1;
- }
-#endif
-
-#ifdef CONFIG_X86_IO_APIC
- for (i = 0; i < nr_ioapics; i++) {
- unsigned long ioapic_phys = mp_ioapics[i].mp_apicaddr;
-
- if (base == ioapic_phys && (res->flags & IORESOURCE_MEM)) {
- dev_info(&dev->dev, "BAR has ioapic at %08lx-%08lx\n",
- base, base + size - 1);
- return 1;
- }
- }
-#endif
-
-#ifdef CONFIG_PCI_MMCONFIG
- for (i = 0; i < pci_mmcfg_config_num; i++) {
- unsigned long addr;
-
- addr = pci_mmcfg_config[i].address;
- if (base == addr && (res->flags & IORESOURCE_MEM)) {
- dev_info(&dev->dev, "BAR has MMCONFIG at %08lx-%08lx\n",
- base, base + size - 1);
- return 1;
- }
- }
-#endif
-
- return 0;
-}
-
-static int check_platform(struct pci_dev *dev, struct resource *res)
-{
- struct resource *root = NULL;
-
- /*
- * forcibly insert it into the
- * resource tree
- */
- if (res->flags & IORESOURCE_MEM)
- root = &iomem_resource;
- else if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
-
- if (root && check_res_with_valid(dev, res)) {
- insert_resource(root, res);
-
- return 1;
- }
-
- return 0;
-}
/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
@@ -203,8 +128,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
pr = pci_find_parent_resource(dev, r);
if (!r->start || !pr ||
request_resource(pr, r) < 0) {
- if (check_platform(dev, r))
- continue;
dev_err(&dev->dev, "BAR %d: can't "
"allocate resource\n", idx);
/*
@@ -248,8 +171,6 @@ static void __init pcibios_allocate_resources(int pass)
r->flags, disabled, pass);
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0) {
- if (check_platform(dev, r))
- continue;
dev_err(&dev->dev, "BAR %d: can't "
"allocate resource\n", idx);
/* We'll assign a new address later */
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
index 5abbdec..ca433c3 100644
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -122,7 +122,6 @@ extern void e820_register_active_regions(int nid, unsigned long start_pfn,
extern u64 e820_hole_size(u64 start, u64 end);
extern void finish_e820_parsing(void);
extern void e820_reserve_resources(void);
-extern void e820_reserve_resources_late(void);
extern void setup_memory_map(void);
extern char *default_machine_specific_memory_setup(void);
extern char *machine_specific_memory_setup(void);
From: Yinghai Lu <yhlu.kernel@xxxxxxxxx>
Subject: [PATCH] x86: split e820 reserved entries record to late v4

Linus said we should register some entries in e820 later,
so could let BAR res register at first, or even pnp?

this one replace
| commit a2bd7274b47124d2fc4dfdb8c0591f545ba749dd
| Author: Yinghai Lu <yhlu.kernel@xxxxxxxxx>
| Date: Mon Aug 25 00:56:08 2008 -0700
|
| x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet against BAR, v3

v2: insert e820 reserve resources before pnp_system_init
v3: fix merging problem in tip/x86/core
please drop the one in tip/x86/core use this one instead
v4: address Linus's review about comments and condition in _late()

Signed-off-by: Yinghai Lu <yhlu.kernel@xxxxxxxxx>

---
arch/x86/kernel/e820.c | 24 +++++++++++++++++++++++-
arch/x86/pci/i386.c | 3 +++
include/asm-x86/e820.h | 1 +
3 files changed, 27 insertions(+), 1 deletion(-)

Index: linux-2.6/arch/x86/kernel/e820.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/e820.c
+++ linux-2.6/arch/x86/kernel/e820.c
@@ -1271,6 +1271,7 @@ static inline const char *e820_type_to_s
/*
* Mark e820 reserved areas as busy for the resource manager.
*/
+static struct resource __initdata *e820_res;
void __init e820_reserve_resources(void)
{
int i;
@@ -1278,6 +1279,7 @@ void __init e820_reserve_resources(void)
u64 end;

res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
+ e820_res = res;
for (i = 0; i < e820.nr_map; i++) {
end = e820.map[i].addr + e820.map[i].size - 1;
#ifndef CONFIG_RESOURCES_64BIT
@@ -1291,7 +1293,14 @@ void __init e820_reserve_resources(void)
res->end = end;

res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- insert_resource(&iomem_resource, res);
+
+ /*
+ * don't register the region that could be conflicted with
+ * pci device BAR resource and insert them later in
+ * pcibios_resource_survey()
+ */
+ if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20))
+ insert_resource(&iomem_resource, res);
res++;
}

@@ -1303,6 +1312,19 @@ void __init e820_reserve_resources(void)
}
}

+void __init e820_reserve_resources_late(void)
+{
+ int i;
+ struct resource *res;
+
+ res = e820_res;
+ for (i = 0; i < e820.nr_map; i++) {
+ if (!res->parent && res->end)
+ insert_resource(&iomem_resource, res);
+ res++;
+ }
+}
+
char *__init default_machine_specific_memory_setup(void)
{
char *who = "BIOS-e820";
Index: linux-2.6/arch/x86/pci/i386.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/i386.c
+++ linux-2.6/arch/x86/pci/i386.c
@@ -33,6 +33,7 @@
#include <linux/bootmem.h>

#include <asm/pat.h>
+#include <asm/e820.h>

#include "pci.h"

@@ -230,6 +231,8 @@ void __init pcibios_resource_survey(void
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
+
+ e820_reserve_resources_late();
}

/**
Index: linux-2.6/include/asm-x86/e820.h
===================================================================
--- linux-2.6.orig/include/asm-x86/e820.h
+++ linux-2.6/include/asm-x86/e820.h
@@ -122,6 +122,7 @@ extern void e820_register_active_regions
extern u64 e820_hole_size(u64 start, u64 end);
extern void finish_e820_parsing(void);
extern void e820_reserve_resources(void);
+extern void e820_reserve_resources_late(void);
extern void setup_memory_map(void);
extern char *default_machine_specific_memory_setup(void);
extern char *machine_specific_memory_setup(void);