* [PATCH] resource/x86: add sticky resource type
@ 2008-08-28 1:56 Yinghai Lu
2008-08-28 8:21 ` Ingo Molnar
0 siblings, 1 reply; 4+ messages in thread
From: Yinghai Lu @ 2008-08-28 1:56 UTC (permalink / raw)
To: Ingo Molnar, Thomas Gleixner, H. Peter Anvin, Andrew Morton
Cc: linux-kernel, Yinghai Lu
Ingo suggest to use sticky resource type to record fixed resource.
so could check that BAR and avoid update it after request_resource failed.
and we could remove tricky code about insert some resource with late_initcall.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
---
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 ++--------------------------------
include/linux/ioport.h | 3 ++
kernel/resource.c | 58 +++++++++++++++++++++++++++++++++++++++++
7 files changed, 83 insertions(+), 138 deletions(-)
Index: linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/boot.c
+++ linux-2.6/arch/x86/kernel/acpi/boot.c
@@ -702,30 +702,17 @@ static int __init acpi_parse_hpet(struct
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
Index: linux-2.6/arch/x86/kernel/apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic.c
+++ linux-2.6/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(cha
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);
Index: linux-2.6/arch/x86/kernel/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/io_apic.c
+++ linux-2.6/arch/x86/kernel/io_apic.c
@@ -3851,7 +3851,7 @@ static struct resource * __init ioapic_s
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;
}
@@ -3900,30 +3900,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);
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
@@ -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 p
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
+ sticky_res = check_with_sticky_res(res);
-#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;
- }
+ 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;
}
Index: linux-2.6/include/linux/ioport.h
===================================================================
--- linux-2.6.orig/include/linux/ioport.h
+++ linux-2.6/include/linux/ioport.h
@@ -48,6 +48,8 @@ struct resource_list {
#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */
#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */
+#define IORESOURCE_STICKY 0x08000000
+
#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000
#define IORESOURCE_AUTO 0x40000000
@@ -109,6 +111,7 @@ extern struct resource iomem_resource;
extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
extern int insert_resource(struct resource *parent, struct resource *new);
+extern struct resource *check_with_sticky_res(struct resource *bar_res);
extern int allocate_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
resource_size_t max, resource_size_t align,
Index: linux-2.6/kernel/resource.c
===================================================================
--- linux-2.6.orig/kernel/resource.c
+++ linux-2.6/kernel/resource.c
@@ -586,6 +586,64 @@ int __check_region(struct resource *pare
EXPORT_SYMBOL(__check_region);
/**
+ * check_with_sticky_res
+ * @bar_res: objective resource descriptor
+ *
+ * return res: identically to bar_res, or near that
+ */
+struct resource *check_with_sticky_res(struct resource *bar_res)
+{
+ struct resource *parent;
+ struct resource *res;
+
+ if (bar_res->flags | IORESOURCE_MEM)
+ parent = &iomem_resource;
+ else if (bar_res->flags | IORESOURCE_IO)
+ parent = &ioport_resource;
+ else
+ return NULL;
+
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (res) {
+ res->name = bar_res->name;
+ res->start = bar_res->start;
+ res->end = bar_res->end;
+ res->flags = bar_res->flags | IORESOURCE_BUSY;
+
+
+ write_lock(&resource_lock);
+
+ for (;;) {
+ struct resource *conflict;
+
+ conflict = __request_resource(parent, res);
+ if (!conflict) {
+ /* not found it */
+ break;
+ }
+ if (conflict != parent) {
+ parent = conflict;
+ if (!(conflict->flags & IORESOURCE_STICKY))
+ continue;
+ } else
+ parent = NULL;
+
+ kfree(res);
+ res = NULL;
+ break;
+ }
+ write_unlock(&resource_lock);
+ }
+
+ if (res) {
+ release_resource(res);
+ kfree(res);
+ }
+
+ return parent;
+}
+
+/**
* __release_region - release a previously reserved resource region
* @parent: parent resource descriptor
* @start: resource start address
Index: linux-2.6/arch/x86/pci/mmconfig-shared.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/mmconfig-shared.c
+++ linux-2.6/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_hostbr
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_reso
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
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);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] resource/x86: add sticky resource type
2008-08-28 1:56 [PATCH] resource/x86: add sticky resource type Yinghai Lu
@ 2008-08-28 8:21 ` Ingo Molnar
2008-08-28 17:20 ` Linus Torvalds
0 siblings, 1 reply; 4+ messages in thread
From: Ingo Molnar @ 2008-08-28 8:21 UTC (permalink / raw)
To: Yinghai Lu
Cc: Thomas Gleixner, H. Peter Anvin, Andrew Morton, linux-kernel,
Linus Torvalds, Jesse Barnes
* Yinghai Lu <yhlu.kernel@gmail.com> wrote:
> Ingo suggest to use sticky resource type to record fixed resource. so
> could check that BAR and avoid update it after request_resource
> failed.
>
> and we could remove tricky code about insert some resource with
> late_initcall.
very nice patch! I've split your patch into two, and applied the
kernel/resource.c and include/linux/ioresource.h core bits to the
tip/core/resources topic branch - see the first patch below. (i renamed
the new API to check_sticky_resource())
Then i've merged this topic branch into irq/sparseirq and applied the
x86 bits that use this new facility to irq/sparseirq [on which it has
many dependencies, io_apic.c and apic.c got unified, etc.]. See the
second patch below.
Especially the second patch shows how much fragile resource code we are
able to remove this way:
5 files changed, 22 insertions(+), 138 deletions(-)
nice work.
Does anyone have any suggestions of how to improve this some more? (or
do it differently)
Ingo
----------------------->
>From 0fec91fc00059401dc756ad635975bea8f813309 Mon Sep 17 00:00:00 2001
From: Yinghai Lu <yhlu.kernel@gmail.com>
Date: Wed, 27 Aug 2008 18:56:23 -0700
Subject: [PATCH] IO resources: add sticky resource type
Ingo suggested to use sticky resource type to record fixed resource.
That way we could check that BAR in the PCI init code and avoid updating
it after request_resource failed.
That way we could remove some tricky code about insert some platform
resources with late_initcall.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
include/linux/ioport.h | 3 ++
kernel/resource.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 22d2115..db53613 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -48,6 +48,8 @@ struct resource_list {
#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */
#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */
+#define IORESOURCE_STICKY 0x08000000
+
#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000
#define IORESOURCE_AUTO 0x40000000
@@ -109,6 +111,7 @@ extern struct resource iomem_resource;
extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
extern int insert_resource(struct resource *parent, struct resource *new);
+extern struct resource *check_sticky_resource(struct resource *bar_res);
extern int allocate_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
resource_size_t max, resource_size_t align,
diff --git a/kernel/resource.c b/kernel/resource.c
index f5b518e..957afa7 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -586,6 +586,64 @@ int __check_region(struct resource *parent, resource_size_t start,
EXPORT_SYMBOL(__check_region);
/**
+ * check_sticky_resource
+ * @bar_res: target resource descriptor
+ *
+ * return res: identical to bar_res, or overlapping it
+ */
+struct resource *check_sticky_resource(struct resource *bar_res)
+{
+ struct resource *parent;
+ struct resource *res;
+
+ if (bar_res->flags | IORESOURCE_MEM)
+ parent = &iomem_resource;
+ else if (bar_res->flags | IORESOURCE_IO)
+ parent = &ioport_resource;
+ else
+ return NULL;
+
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (res) {
+ res->name = bar_res->name;
+ res->start = bar_res->start;
+ res->end = bar_res->end;
+ res->flags = bar_res->flags | IORESOURCE_BUSY;
+
+ write_lock(&resource_lock);
+
+ for (;;) {
+ struct resource *conflict;
+
+ conflict = __request_resource(parent, res);
+ if (!conflict) {
+ /* not found */
+ break;
+ }
+ if (conflict != parent) {
+ parent = conflict;
+ if (!(conflict->flags & IORESOURCE_STICKY))
+ continue;
+ } else {
+ parent = NULL;
+ }
+
+ kfree(res);
+ res = NULL;
+ break;
+ }
+ write_unlock(&resource_lock);
+ }
+
+ if (res) {
+ release_resource(res);
+ kfree(res);
+ }
+
+ return parent;
+}
+
+/**
* __release_region - release a previously reserved resource region
* @parent: parent resource descriptor
* @start: resource start address
----------------------->
>From b785e212314cf2ed1b0c17a6df1041016437b528 Mon Sep 17 00:00:00 2001
From: Yinghai Lu <yhlu.kernel@gmail.com>
Date: Wed, 27 Aug 2008 18:56:23 -0700
Subject: [PATCH] resource/x86: use sticky resource type for platform resources
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@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
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);
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] resource/x86: add sticky resource type
2008-08-28 8:21 ` Ingo Molnar
@ 2008-08-28 17:20 ` Linus Torvalds
2008-08-28 20:17 ` Ingo Molnar
0 siblings, 1 reply; 4+ messages in thread
From: Linus Torvalds @ 2008-08-28 17:20 UTC (permalink / raw)
To: Ingo Molnar
Cc: Yinghai Lu, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
linux-kernel, Jesse Barnes
On Thu, 28 Aug 2008, Ingo Molnar wrote:
>
> Does anyone have any suggestions of how to improve this some more? (or
> do it differently)
As far as I can see, THIS IS TOTALLY BROKEN.
There's a reason why we add the broken resources LATE. There's a reason we
_have_ to add them late.
Trying to come up with these braindamaged schemes to avoid doing it right
is wrong. Don't do it.
The reason? Those bogus resources that the BIOS reports are simply NOT
TRUSTWORTHY. They may actually be in all the wrong places, including
covering a resource half-way, or crossing two real resources.
Yes, it's rare. But it happens. Which is why we should not do these broken
things that _incorrectly_ assume that the BIOS resources will only ever be
totally contained within a BAR, or will totally contain one. Think about
the partial overlap case.
Guys, until you learn that the BIOS resources are _crap_ and at most
random guesses, you shouldn't touch this code! And it has nothing to do
with writing "clean" code, or making things "simple", because quite
frankly, things simply ARE NOT simple!
The fact is, the only reliable way to handle these things has _always_
been to ask the hardware first. Add the broken resources from ACPI and
other BIOS tables _later_. If they conflict, it is the ACPI/BIOS tables
that should be removed.
Why do I have to tell this to people over and over again?
Linus
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] resource/x86: add sticky resource type
2008-08-28 17:20 ` Linus Torvalds
@ 2008-08-28 20:17 ` Ingo Molnar
0 siblings, 0 replies; 4+ messages in thread
From: Ingo Molnar @ 2008-08-28 20:17 UTC (permalink / raw)
To: Linus Torvalds
Cc: Yinghai Lu, Thomas Gleixner, H. Peter Anvin, Andrew Morton,
linux-kernel, Jesse Barnes
* Linus Torvalds <torvalds@linux-foundation.org> wrote:
> The fact is, the only reliable way to handle these things has _always_
> been to ask the hardware first. Add the broken resources from ACPI and
> other BIOS tables _later_. If they conflict, it is the ACPI/BIOS
> tables that should be removed.
i fully agree with that principle, i just messed up implementing it.
'Sticky resources' tried to be exactly the kind of 'untrusted, possibly
wrong' resources, which should not prevent existing PCI resources from
being registered - they would at most prevent new PCI resources from
being allocated over them. (the free space is large enough for us to
take the small/untrusted hint from the BIOS where not to allocate to)
I missed the possibility of a sticky resource not being wide enough and
preventing a BAR from being registered, due to partial overlap. That was
not intended.
I guess this whole patchset has to become a lot wider and a lot more
involved.
Ingo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-08-28 20:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-28 1:56 [PATCH] resource/x86: add sticky resource type Yinghai Lu
2008-08-28 8:21 ` Ingo Molnar
2008-08-28 17:20 ` Linus Torvalds
2008-08-28 20:17 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox