[PATCH] resource/x86: use sticky resource type for platform resources

From: Yinghai Lu
Date: Wed Aug 27 2008 - 21:56:23 EST


Remove tricky (and fragile) late_initcall code that inserted special
platform resources that might overlap with PCI resources.

Instead use the sticky resource type in early init, to make sure these
resources are known to the PCI code already.

>From now on platform code can just register special resources with
the sticky flag set, and the PCI code will not move any overlapping
PCI device resources if there's a conflict.

Signed-off-by: Yinghai Lu <yhlu.kernel@xxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
---
arch/x86/kernel/acpi/boot.c | 17 +------------
arch/x86/kernel/apic.c | 30 ++++++------------------
arch/x86/kernel/io_apic.c | 26 +-------------------
arch/x86/pci/i386.c | 38 +++++-------------------------
arch/x86/pci/mmconfig-shared.c | 49 ++-------------------------------------
5 files changed, 22 insertions(+), 138 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 06aa544..aefa636 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -703,30 +703,17 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table)
hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE);

hpet_res->name = (void *)&hpet_res[1];
- hpet_res->flags = IORESOURCE_MEM;
+ hpet_res->flags = IORESOURCE_MEM | IORESOURCE_STICKY;
snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u",
hpet_tbl->sequence);

hpet_res->start = hpet_address;
hpet_res->end = hpet_address + (1 * 1024) - 1;
+ insert_resource(&iomem_resource, hpet_res);

return 0;
}

-/*
- * hpet_insert_resource inserts the HPET resources used into the resource
- * tree.
- */
-static __init int hpet_insert_resource(void)
-{
- if (!hpet_res)
- return 1;
-
- return insert_resource(&iomem_resource, hpet_res);
-}
-
-late_initcall(hpet_insert_resource);
-
#else
#define acpi_parse_hpet NULL
#endif
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index 0556f37..b8b5bb5 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -132,7 +132,7 @@ int smp_found_config;

static struct resource lapic_resource = {
.name = "Local APIC",
- .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
+ .flags = IORESOURCE_MEM | IORESOURCE_BUSY | IORESOURCE_STICKY,
};

static unsigned int calibration_result;
@@ -1544,11 +1544,16 @@ void __init init_apic_mappings(void)
if (!smp_found_config && detect_init_APIC()) {
apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
apic_phys = __pa(apic_phys);
- } else
+ } else {
apic_phys = mp_lapic_addr;
+ /* Put local APIC into the resource map. */
+ lapic_resource.start = apic_phys;
+ lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
+ insert_resource(&iomem_resource, &lapic_resource);
+ }

set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
- apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
+ apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%8lx)\n",
APIC_BASE, apic_phys);

/*
@@ -2198,22 +2203,3 @@ static int __init apic_set_verbosity(char *arg)
return 0;
}
early_param("apic", apic_set_verbosity);
-
-static int __init lapic_insert_resource(void)
-{
- if (!apic_phys)
- return -1;
-
- /* Put local APIC into the resource map. */
- lapic_resource.start = apic_phys;
- lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
- insert_resource(&iomem_resource, &lapic_resource);
-
- return 0;
-}
-
-/*
- * need call insert after e820_reserve_resources()
- * that is using request_resource
- */
-late_initcall(lapic_insert_resource);
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index d28128e..8496ba7 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -3846,7 +3846,7 @@ static struct resource * __init ioapic_setup_resources(void)

for (i = 0; i < nr_ioapics; i++) {
res[i].name = mem;
- res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY | IORESOURCE_STICKY;
sprintf(mem, "IOAPIC %u", i);
mem += IOAPIC_RESOURCE_NAME_SIZE;
}
@@ -3895,30 +3895,8 @@ fake_ioapic_page:
if (ioapic_res != NULL) {
ioapic_res->start = ioapic_phys;
ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
+ insert_resource(&iomem_resource, ioapic_res);
ioapic_res++;
}
}
}
-
-static int __init ioapic_insert_resources(void)
-{
- int i;
- struct resource *r = ioapic_resources;
-
- if (!r) {
- printk(KERN_ERR
- "IO APIC resources could be not be allocated.\n");
- return -1;
- }
-
- for (i = 0; i < nr_ioapics; i++) {
- insert_resource(&iomem_resource, r);
- r++;
- }
-
- return 0;
-}
-
-/* Insert the IO APIC resources after PCI initialization has occured to handle
- * IO APICS that are mapped in on a BAR in PCI space. */
-late_initcall(ioapic_insert_resources);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index d765da9..023cbc0 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -82,6 +82,7 @@ EXPORT_SYMBOL(pcibios_align_resource);

static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
{
+ struct resource *sticky_res;
unsigned long base;
unsigned long size;
int i;
@@ -93,39 +94,14 @@ static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
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;
+ sticky_res = check_sticky_resource(res);

- 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;
- }
+ if (sticky_res) {
+ dev_info(&dev->dev, "BAR %08lx-%08lx with sticky res %s [%08llx, %08llx]\n",
+ base, base + size - 1, sticky_res->name,
+ sticky_res->start, sticky_res->end);
+ return 1;
}
-#endif

return 0;
}
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index d963576..6d7c179 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -22,9 +22,6 @@
#define MMCONFIG_APER_MIN (2 * 1024*1024)
#define MMCONFIG_APER_MAX (256 * 1024*1024)

-/* Indicate if the mmcfg resources have been placed into the resource table. */
-static int __initdata pci_mmcfg_resources_inserted;
-
static const char __init *pci_mmcfg_e7520(void)
{
u32 win;
@@ -209,7 +206,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
return name != NULL;
}

-static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
+static void __init pci_mmcfg_insert_resources(void)
{
#define PCI_MMCFG_RESOURCE_NAME_LEN 19
int i;
@@ -233,13 +230,10 @@ static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
cfg->pci_segment);
res->start = cfg->address;
res->end = res->start + (num_buses << 20) - 1;
- res->flags = IORESOURCE_MEM | resource_flags;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY | IORESOURCE_STICKY;
insert_resource(&iomem_resource, res);
names += PCI_MMCFG_RESOURCE_NAME_LEN;
}
-
- /* Mark that the resources have been inserted. */
- pci_mmcfg_resources_inserted = 1;
}

static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
@@ -435,15 +429,8 @@ static void __init __pci_mmcfg_init(int early)
return;

if (pci_mmcfg_arch_init()) {
- if (known_bridge)
- pci_mmcfg_insert_resources(IORESOURCE_BUSY);
+ pci_mmcfg_insert_resources();
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
- } else {
- /*
- * Signal not to attempt to insert mmcfg resources because
- * the architecture mmcfg setup could not initialize.
- */
- pci_mmcfg_resources_inserted = 1;
}
}

@@ -456,33 +443,3 @@ void __init pci_mmcfg_late_init(void)
{
__pci_mmcfg_init(0);
}
-
-static int __init pci_mmcfg_late_insert_resources(void)
-{
- /*
- * If resources are already inserted or we are not using MMCONFIG,
- * don't insert the resources.
- */
- if ((pci_mmcfg_resources_inserted == 1) ||
- (pci_probe & PCI_PROBE_MMCONF) == 0 ||
- (pci_mmcfg_config_num == 0) ||
- (pci_mmcfg_config == NULL) ||
- (pci_mmcfg_config[0].address == 0))
- return 1;
-
- /*
- * Attempt to insert the mmcfg resources but not with the busy flag
- * marked so it won't cause request errors when __request_region is
- * called.
- */
- pci_mmcfg_insert_resources(0);
-
- return 0;
-}
-
-/*
- * Perform MMCONFIG resource insertion after PCI initialization to allow for
- * misprogrammed MCFG tables that state larger sizes but actually conflict
- * with other system resources.
- */
-late_initcall(pci_mmcfg_late_insert_resources);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/