[kernel/f15/master] Fix more PCIe ASPM bugs

Chuck Ebbert cebbert at fedoraproject.org
Mon Mar 28 00:13:18 UTC 2011


commit 073133a682770c1b879c184229788ef32e96a622
Author: Chuck Ebbert <cebbert at redhat.com>
Date:   Sun Mar 27 20:14:26 2011 -0400

    Fix more PCIe ASPM bugs
    
    - kworker task over 65% after resume (#683156)
    - ASPM powersave mode does not get enabled

 kernel.spec                                        |   16 ++-
 ...ntain-supported-features-not-enabled-ones.patch |   66 ------------
 ...to-bios-if-not-disabled-from-command-line.patch |   89 ++++++++++++++++
 ...-configured-for-aspm-under-powersave-mode.patch |  112 ++++++++++++++++++++
 4 files changed, 213 insertions(+), 70 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 34fc582..b6ead48 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -51,7 +51,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be prepended with "0.", so
 # for example a 3 here will become 0.3
 #
-%global baserelease 7
+%global baserelease 8
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -633,7 +633,6 @@ Patch204: linux-2.6-debug-always-inline-kzalloc.patch
 Patch380: linux-2.6-defaults-pci_no_msi.patch
 Patch381: linux-2.6-defaults-pci_use_crs.patch
 Patch383: linux-2.6-defaults-aspm.patch
-Patch386: pci-_osc-supported-field-should-contain-supported-features-not-enabled-ones.patch
 
 Patch385: ima-allow-it-to-be-completely-disabled-and-default-off.patch
 
@@ -728,6 +727,8 @@ Patch12200: acpi_reboot.patch
 Patch12203: linux-2.6-usb-pci-autosuspend.patch
 Patch12204: linux-2.6-enable-more-pci-autosuspend.patch
 Patch12205: runtime_pm_fixups.patch
+Patch12206: pci-acpi-report-aspm-support-to-bios-if-not-disabled-from-command-line.patch
+Patch12207: pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch
 
 Patch12303: dmar-disable-when-ricoh-multifunction.patch
 
@@ -1247,8 +1248,10 @@ ApplyPatch linux-2.6-defaults-pci_no_msi.patch
 ApplyPatch linux-2.6-defaults-pci_use_crs.patch
 # enable ASPM by default on hardware we expect to work
 ApplyPatch linux-2.6-defaults-aspm.patch
-# rhbz#638912
-#ApplyPatch pci-_osc-supported-field-should-contain-supported-features-not-enabled-ones.patch
+# rhbz #683156
+ApplyPatch pci-acpi-report-aspm-support-to-bios-if-not-disabled-from-command-line.patch
+#
+ApplyPatch pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch
 
 #ApplyPatch ima-allow-it-to-be-completely-disabled-and-default-off.patch
 
@@ -1980,6 +1983,11 @@ fi
 # and build.
 
 %changelog
+* Sat Mar 26 2011 Chuck Ebbert <cebbert at redhat.com>
+- Fix more PCIe ASPM bugs:
+   kworker task over 65% after resume (#683156)
+   ASPM powersave mode does not get enabled
+
 * Sat Mar 26 2011 Chuck Ebbert <cebbert at redhat.com> 2.6.38.2-7.rc1
 - Linux 2.6.38.2-rc1
 
diff --git a/pci-acpi-report-aspm-support-to-bios-if-not-disabled-from-command-line.patch b/pci-acpi-report-aspm-support-to-bios-if-not-disabled-from-command-line.patch
new file mode 100644
index 0000000..8dccd1a
--- /dev/null
+++ b/pci-acpi-report-aspm-support-to-bios-if-not-disabled-from-command-line.patch
@@ -0,0 +1,89 @@
+From: Rafael J. Wysocki <rjw at sisk.pl>
+Date: Sat, 5 Mar 2011 12:21:51 +0000 (+0100)
+Subject: PCI/ACPI: Report ASPM support to BIOS if not disabled from command line
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8b8bae901ce23addbdcdb54fa1696fb2d049feb5
+
+PCI/ACPI: Report ASPM support to BIOS if not disabled from command line
+
+We need to distinguish the situation in which ASPM support is
+disabled from the command line or through .config from the situation
+in which it is disabled, because the hardware or BIOS can't handle
+it.  In the former case we should not report ASPM support to the BIOS
+through ACPI _OSC, but in the latter case we should do that.
+
+Introduce pcie_aspm_support_enabled() that can be used by
+acpi_pci_root_add() to determine whether or not it should report ASPM
+support to the BIOS through _OSC.
+
+Cc: stable at kernel.org
+References: https://bugzilla.kernel.org/show_bug.cgi?id=29722
+References: https://bugzilla.kernel.org/show_bug.cgi?id=20232
+Reported-and-tested-by: Ortwin Glück <odi at odi.ch>
+Reviewed-by: Kenji Kaneshige <kaneshige.kenji at jp.fujitsu.com>
+Tested-by: Kenji Kaneshige <kaneshige.kenji at jp.fujitsu.com>
+Signed-off-by: Rafael J. Wysocki <rjw at sisk.pl>
+Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
+---
+
+diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
+index 8524939..c7358dd 100644
+--- a/drivers/acpi/pci_root.c
++++ b/drivers/acpi/pci_root.c
+@@ -564,7 +564,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
+ 	/* Indicate support for various _OSC capabilities. */
+ 	if (pci_ext_cfg_avail(root->bus->self))
+ 		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
+-	if (pcie_aspm_enabled())
++	if (pcie_aspm_support_enabled())
+ 		flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
+ 			OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
+ 	if (pci_msi_enabled())
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index 3188cd9..bbdb4fd 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -69,6 +69,7 @@ struct pcie_link_state {
+ };
+ 
+ static int aspm_disabled, aspm_force, aspm_clear_state;
++static bool aspm_support_enabled = true;
+ static DEFINE_MUTEX(aspm_lock);
+ static LIST_HEAD(link_list);
+ 
+@@ -896,6 +897,7 @@ static int __init pcie_aspm_disable(char *str)
+ {
+ 	if (!strcmp(str, "off")) {
+ 		aspm_disabled = 1;
++		aspm_support_enabled = false;
+ 		printk(KERN_INFO "PCIe ASPM is disabled\n");
+ 	} else if (!strcmp(str, "force")) {
+ 		aspm_force = 1;
+@@ -930,3 +932,8 @@ int pcie_aspm_enabled(void)
+ }
+ EXPORT_SYMBOL(pcie_aspm_enabled);
+ 
++bool pcie_aspm_support_enabled(void)
++{
++	return aspm_support_enabled;
++}
++EXPORT_SYMBOL(pcie_aspm_support_enabled);
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 16c9f2e..96f70d7 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1002,12 +1002,11 @@ extern bool pcie_ports_auto;
+ #endif
+ 
+ #ifndef CONFIG_PCIEASPM
+-static inline int pcie_aspm_enabled(void)
+-{
+-	return 0;
+-}
++static inline int pcie_aspm_enabled(void) { return 0; }
++static inline bool pcie_aspm_support_enabled(void) { return false; }
+ #else
+ extern int pcie_aspm_enabled(void);
++extern bool pcie_aspm_support_enabled(void);
+ #endif
+ 
+ #ifdef CONFIG_PCIEAER
diff --git a/pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch b/pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch
new file mode 100644
index 0000000..0c7f592
--- /dev/null
+++ b/pci-pcie-links-may-not-get-configured-for-aspm-under-powersave-mode.patch
@@ -0,0 +1,112 @@
+From: Naga Chumbalkar <nagananda.chumbalkar at hp.com>
+Date: Mon, 21 Mar 2011 03:29:08 +0000 (+0000)
+Subject: PCI: PCIe links may not get configured for ASPM under POWERSAVE mode
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=1a680b7c325882188865f05b9a88d32f75f26495
+
+PCI: PCIe links may not get configured for ASPM under POWERSAVE mode
+
+v3 -> v2: Moved ASPM enabling logic to pci_set_power_state()
+v2 -> v1: Preserved the logic in pci_raw_set_power_state()
+	: Added ASPM enabling logic after scanning Root Bridge
+	: http://marc.info/?l=linux-pci&m=130046996216391&w=2
+v1	: http://marc.info/?l=linux-pci&m=130013164703283&w=2
+
+The assumption made in commit 41cd766b065970ff6f6c89dd1cf55fa706c84a3d
+(PCI: Don't enable aspm before drivers have had a chance to veto it) that
+pci_enable_device() will result in re-configuring ASPM when aspm_policy is
+POWERSAVE is no longer valid.  This is due to commit
+97c145f7c87453cec90e91238fba5fe2c1561b32 (PCI: read current power state
+at enable time) which resets dev->current_state to D0. Due to this the
+call to pcie_aspm_pm_state_change() is never made. Note the equality check
+(below) that returns early:
+./drivers/pci/pci.c: pci_raw_set_pci_power_state()
+546         /* Check if we're already there */
+547         if (dev->current_state == state)
+548                 return 0;
+
+Therefore OSPM never configures the PCIe links for ASPM to turn them "on".
+
+Fix it by configuring ASPM from the pci_enable_device() code path. This
+also allows a driver such as the e1000e networking driver a chance to
+disable ASPM (L0s, L1), if need be, prior to enabling the device. A
+driver may perform this action if the device is known to mis-behave
+wrt ASPM.
+
+Signed-off-by: Naga Chumbalkar <nagananda.chumbalkar at hp.com>
+Acked-by: Rafael J. Wysocki <rjw at sisk.pl>
+Cc: Matthew Garrett <mjg59 at srcf.ucam.org>
+Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
+---
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index b714d78..2472e71 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -740,6 +740,12 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
+ 
+ 	if (!__pci_complete_power_transition(dev, state))
+ 		error = 0;
++	/*
++	 * When aspm_policy is "powersave" this call ensures
++	 * that ASPM is configured.
++	 */
++	if (!error && dev->bus->self)
++		pcie_aspm_powersave_config_link(dev->bus->self);
+ 
+ 	return error;
+ }
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index bbdb4fd..e61b82e 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -708,6 +708,28 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
+ 	up_read(&pci_bus_sem);
+ }
+ 
++void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
++{
++	struct pcie_link_state *link = pdev->link_state;
++
++	if (aspm_disabled || !pci_is_pcie(pdev) || !link)
++		return;
++
++	if (aspm_policy != POLICY_POWERSAVE)
++		return;
++
++	if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
++	    (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
++		return;
++
++	down_read(&pci_bus_sem);
++	mutex_lock(&aspm_lock);
++	pcie_config_aspm_path(link);
++	pcie_set_clkpm(link, policy_to_clkpm_state(link));
++	mutex_unlock(&aspm_lock);
++	up_read(&pci_bus_sem);
++}
++
+ /*
+  * pci_disable_link_state - disable pci device's link state, so the link will
+  * never enter specific states
+diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
+index ce68105..67cb3ae 100644
+--- a/include/linux/pci-aspm.h
++++ b/include/linux/pci-aspm.h
+@@ -26,6 +26,7 @@
+ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
+ extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
+ extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
++extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
+ extern void pci_disable_link_state(struct pci_dev *pdev, int state);
+ extern void pcie_clear_aspm(void);
+ extern void pcie_no_aspm(void);
+@@ -39,6 +40,9 @@ static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev)
+ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
+ {
+ }
++static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
++{
++}
+ static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
+ {
+ }


More information about the scm-commits mailing list