[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#700544: linux-image-2.6.32-5-amd64: Error in acpi_memory_enable_device on memory hotplug, one memory bank missing



Control: tag -1 patch moreinfo

On Thu, 2013-02-14 at 15:08 +0100, Bernhard Schmidt wrote:
> Hello Ben,
> 
> > This is not memory, it's MMIO (memory-mapped input/output) for the
> > emulated VGA card.  The kernel controls the addresses used for MMIO for
> > PCI devices, but does not control the addresses used for RAM.
> > Apparently the system firmware (or in this case the hypervisor) can
> > provide hints through ACPI about what addresses it should use, to avoid
> > conflicting with hot-added RAM.  But the kernel version in squeeze
> > ignores those hints.
> > 
> > Does the kernel parameter 'pci=use_crs' avoid this?
> 
> That works fine, thanks! Can this somehow be patched in the kernel or
> shall we just change our boot parameters?

Please test a kernel with the attached patches, applied in the order:

x86-PCI-for-debuggability-show-host-bridge-windows-e.patch
x86-PCI-use-host-bridge-_CRS-info-by-default-on-2008.patch
x86-PCI-Use-_CRS-by-default-on-VMware.patch

and without adding the kernel parameter.

This should result in a boot log message:

    PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug

If VMware was not detected as I intended, then you'll see:

    PCI: Ignoring host bridge windows from ACPI; if necessary, use "pci=use_crs" and report a bug

Ben.

-- 
Ben Hutchings
Absolutum obsoletum. (If it works, it's out of date.) - Stafford Beer
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Date: Tue, 23 Feb 2010 10:24:41 -0700
Subject: x86/PCI: use host bridge _CRS info by default on 2008 and newer
 machines

Part of commit 7bc5e3f2be32ae6fb0c74cd0f707f986b3a01a26 upstream.

The main benefit of using ACPI host bridge window information is that
we can do better resource allocation in systems with multiple host bridges,
e.g., http://bugzilla.kernel.org/show_bug.cgi?id=14183

Sometimes we need _CRS information even if we only have one host bridge,
e.g., https://bugs.launchpad.net/ubuntu/+source/linux/+bug/341681

Most of these systems are relatively new, so this patch turns on
"pci=use_crs" only on machines with a BIOS date of 2008 or newer.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[bwh: Conservative backport to squeeze:
 - Adjust context
 - Don't enable it based on BIOS date, but do start applying quirks for
   specific models]
---
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1927,8 +1927,11 @@ and is between 256 and 4096 characters. It is defined in the file
 				IRQ routing is enabled.
 		noacpi		[X86] Do not use ACPI for IRQ routing
 				or for PCI scanning.
-		use_crs		[X86] Use _CRS for PCI resource
-				allocation.
+		use_crs		[X86] Use PCI host bridge window information
+				from ACPI.  If you need to use this, please
+				report a bug.
+		nocrs		[X86] Ignore PCI host bridge windows from ACPI.
+			        If you need to use this, please report a bug.
 		routeirq	Do IRQ routing for all PCI devices.
 				This is normally done in pci_enable_device(),
 				so this option is a temporary workaround
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -98,6 +98,7 @@ ia64_acpi_release_global_lock (unsigned int *lock)
 #endif
 #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
 static inline void disable_acpi(void) { }
+static inline void pci_acpi_crs_quirks(void) { }
 
 const char *acpi_get_sysname (void);
 int acpi_request_vector (u32 int_type);
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -29,6 +29,7 @@
 #define PCI_CHECK_ENABLE_AMD_MMCONF	0x20000
 #define PCI_HAS_IO_ECS		0x40000
 #define PCI_NOASSIGN_ROMS	0x80000
+#define PCI_ROOT_NO_CRS		0x100000
 
 extern unsigned int pci_probe;
 extern unsigned long pirq_table_addr;
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -14,6 +14,46 @@ struct pci_root_info {
 	int busnum;
 };
 
+static bool pci_use_crs = false;
+
+static int __init set_use_crs(const struct dmi_system_id *id)
+{
+	pci_use_crs = true;
+	return 0;
+}
+
+static const struct dmi_system_id pci_use_crs_table[] __initconst = {
+	/* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
+	{
+		.callback = set_use_crs,
+		.ident = "IBM System x3800",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
+		},
+	},
+	{}
+};
+
+void __init pci_acpi_crs_quirks(void)
+{
+	dmi_check_system(pci_use_crs_table);
+
+	/*
+	 * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
+	 * takes precedence over anything we figured out above.
+	 */
+	if (pci_probe & PCI_ROOT_NO_CRS)
+		pci_use_crs = false;
+	else if (pci_probe & PCI_USE__CRS)
+		pci_use_crs = true;
+
+	printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
+	       "if necessary, use \"pci=%s\" and report a bug\n",
+	       pci_use_crs ? "Using" : "Ignoring",
+	       pci_use_crs ? "nocrs" : "use_crs");
+}
+
 static acpi_status
 resource_to_addr(struct acpi_resource *resource,
 			struct acpi_resource_address64 *addr)
@@ -107,7 +147,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 	res->end = end;
 	res->child = NULL;
 
-	if (!(pci_probe & PCI_USE__CRS)) {
+	if (!pci_use_crs) {
 		printk(KERN_DEBUG "host bridge window %pR (ignored)\n", res);
 		return AE_OK;
 	}
@@ -130,11 +170,6 @@ get_current_resources(struct acpi_device *device, int busnum,
 	struct pci_root_info info;
 	size_t size;
 
-	if (!(pci_probe & PCI_USE__CRS))
-		dev_info(&device->dev,
-			 "ignoring host bridge windows from ACPI; "
-			 "boot with \"pci=use_crs\" to use them\n");
-
 	info.bus = bus;
 	info.res_num = 0;
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -518,6 +518,9 @@ char * __devinit  pcibios_setup(char *str)
 	} else if (!strcmp(str, "use_crs")) {
 		pci_probe |= PCI_USE__CRS;
 		return NULL;
+	} else if (!strcmp(str, "nocrs")) {
+		pci_probe |= PCI_ROOT_NO_CRS;
+		return NULL;
 	} else if (!strcmp(str, "earlydump")) {
 		pci_early_dump_regs = 1;
 		return NULL;
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -606,6 +606,7 @@ static int __init acpi_pci_root_init(void)
 	if (acpi_pci_disabled)
 		return 0;
 
+	pci_acpi_crs_quirks();
 	if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
 		return -ENODEV;
 
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -104,6 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device);
 
 struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
 				   int bus);
+void pci_acpi_crs_quirks(void);
 
 /* --------------------------------------------------------------------------
                                     Processor
From: Ben Hutchings <ben@decadent.org.uk>
Date: Fri, 15 Feb 2013 02:35:13 +0000
Subject: x86/PCI: Use _CRS by default on VMware
Bug-Debian: http://bugs.debian.org/700544

VMware supports memory hotplug and we need to avoid mapping PCI devices
in the address ranges where it will use for this.

This change is effectively included in commit
7bc5e3f2be32ae6fb0c74cd0f707f986b3a01a26 upstream, but I don't
want to include that in squeeze in case it causes a regression.

--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -32,6 +32,14 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
 		},
 	},
+	/* http://bugs.debian.org/700544 */
+	{
+		.callback = set_use_crs,
+		.ident = "VMware",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "VMware Virtual Platform"),
+		},
+	},
 	{}
 };
 
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Date: Wed, 4 Nov 2009 10:39:13 -0700
Subject: x86/PCI: for debuggability, show host bridge windows even when
 ignoring _CRS

commit f1db6fde09e201218f488d7205a7cd7bc448d496 upstream.

We have occasional problems with PCI resource allocation, and sometimes
they could be avoided by paying attention to what ACPI tells us about
the host bridges.  This patch doesn't change the behavior, but it prints
window information that should make debugging easier.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[bwh: Backported to 2.6.32:
 - Adjust context
 - Don't use pci_root_info::bridge in debug message]
---
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -91,11 +91,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 	start = addr.minimum + addr.translation_offset;
 	end = start + addr.address_length - 1;
 	if (info->res_num >= max_root_bus_resources) {
-		printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
-			"from %s for %s due to _CRS returning more than "
-			"%d resource descriptors\n", (unsigned long) start,
-			(unsigned long) end, root->name, info->name,
-			max_root_bus_resources);
+		if (pci_probe & PCI_USE__CRS)
+			printk(KERN_WARNING "PCI: Failed to allocate "
+			       "0x%lx-0x%lx from %s for %s due to _CRS "
+			       "returning more than %d resource descriptors\n",
+			       (unsigned long) start, (unsigned long) end,
+			       root->name, info->name, max_root_bus_resources);
 		return AE_OK;
 	}
 
@@ -106,6 +107,11 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 	res->end = end;
 	res->child = NULL;
 
+	if (!(pci_probe & PCI_USE__CRS)) {
+		printk(KERN_DEBUG "host bridge window %pR (ignored)\n", res);
+		return AE_OK;
+	}
+
 	if (insert_resource(root, res)) {
 		printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
 			"from %s for %s\n", (unsigned long) res->start,
@@ -124,6 +131,11 @@ get_current_resources(struct acpi_device *device, int busnum,
 	struct pci_root_info info;
 	size_t size;
 
+	if (!(pci_probe & PCI_USE__CRS))
+		dev_info(&device->dev,
+			 "ignoring host bridge windows from ACPI; "
+			 "boot with \"pci=use_crs\" to use them\n");
+
 	info.bus = bus;
 	info.res_num = 0;
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
@@ -209,9 +221,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
 	} else {
 		bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
 		if (bus) {
-			if (pci_probe & PCI_USE__CRS)
-				get_current_resources(device, busnum, domain,
-							bus);
+			get_current_resources(device, busnum, domain, bus);
 			bus->subordinate = pci_scan_child_bus(bus);
 		}
 	}

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: