Fix more PCIe ASPM bugs
- kworker task over 65% after resume (#683156) - ASPM powersave mode does not get enabled
This commit is contained in:
parent
1590df9db8
commit
073133a682
16
kernel.spec
16
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@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@redhat.com> 2.6.38.2-7.rc1
|
||||
- Linux 2.6.38.2-rc1
|
||||
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
commit 885c252ffb059dc493200bdb981bdd21cabe4442
|
||||
Author: Matthew Garrett <mjg@redhat.com>
|
||||
Date: Thu Dec 9 18:31:59 2010 -0500
|
||||
|
||||
PCI: _OSC "supported" field should contain supported features, not enabled ones
|
||||
|
||||
From testing with Windows, the call to the PCI root _OSC method includes
|
||||
the full set of features supported by the operating system even if the
|
||||
hardware has already indicated that it doesn't support ASPM or MSI.
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=638912 is a case where making
|
||||
the _OSC call will incorrectly configure the chipset unless the supported
|
||||
field has bits 1, 2 and 4 set. Rework the functionality to ensure that
|
||||
we match this behaviour.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
|
||||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
|
||||
index 96668ad..afb5d08 100644
|
||||
--- a/drivers/acpi/pci_root.c
|
||||
+++ b/drivers/acpi/pci_root.c
|
||||
@@ -450,7 +450,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
struct acpi_pci_root *root;
|
||||
acpi_handle handle;
|
||||
struct acpi_device *child;
|
||||
- u32 flags, base_flags;
|
||||
+ u32 flags;
|
||||
|
||||
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
||||
if (!root)
|
||||
@@ -498,10 +498,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
device->driver_data = root;
|
||||
|
||||
/*
|
||||
- * All supported architectures that use ACPI have support for
|
||||
- * PCI domains, so we indicate this in _OSC support capabilities.
|
||||
+ * Indicate support for various _OSC capabilities. These match
|
||||
+ * what the operating system supports, not what the hardware supports,
|
||||
+ * so they shouldn't be conditional on functionality that's been
|
||||
+ * blacklisted
|
||||
*/
|
||||
- flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
|
||||
+ flags = OSC_EXT_PCI_CONFIG_SUPPORT | OSC_ACTIVE_STATE_PWR_SUPPORT |
|
||||
+ OSC_CLOCK_PWR_CAPABILITY_SUPPORT |
|
||||
+ OSC_PCI_SEGMENT_GROUPS_SUPPORT | OSC_MSI_SUPPORT;
|
||||
+
|
||||
acpi_pci_osc_support(root, flags);
|
||||
|
||||
/*
|
||||
@@ -555,17 +560,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
list_for_each_entry(child, &device->children, node)
|
||||
acpi_pci_bridge_scan(child);
|
||||
|
||||
- /* Indicate support for various _OSC capabilities. */
|
||||
- if (pci_ext_cfg_avail(root->bus->self))
|
||||
- flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
|
||||
- if (pcie_aspm_enabled())
|
||||
- flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
|
||||
- OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
|
||||
- if (pci_msi_enabled())
|
||||
- flags |= OSC_MSI_SUPPORT;
|
||||
- if (flags != base_flags)
|
||||
- acpi_pci_osc_support(root, flags);
|
||||
-
|
||||
pci_acpi_add_bus_pm_notifier(device, root->bus);
|
||||
if (device->wakeup.flags.run_wake)
|
||||
device_set_run_wake(root->bus->bridge, true);
|
|
@ -0,0 +1,89 @@
|
|||
From: Rafael J. Wysocki <rjw@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@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@odi.ch>
|
||||
Reviewed-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
|
||||
Tested-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
|
||||
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@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
|
|
@ -0,0 +1,112 @@
|
|||
From: Naga Chumbalkar <nagananda.chumbalkar@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@hp.com>
|
||||
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@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)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue