From 7570a333d8b00e7fd4b05d898e353000a70210ce Mon Sep 17 00:00:00 2001 From: MUNEDA Takahiro Date: Thu, 2 Feb 2012 11:09:22 -0500 Subject: PCI: Add pcie_hp=nomsi to disable MSI/MSI-X for pciehp driver Add a parameter to avoid using MSI/MSI-X for PCIe native hotplug; it's known to be buggy on some platforms. In my environment, while shutting down, following stack trace is shown sometimes. irq 16: nobody cared (try booting with the "irqpoll" option) Pid: 1081, comm: reboot Not tainted 3.2.0 #1 Call Trace: [] __report_bad_irq+0x3d/0xe0 [] note_interrupt+0x15c/0x210 [] handle_irq_event_percpu+0xb5/0x210 [] handle_irq_event+0x41/0x70 [] handle_fasteoi_irq+0x55/0xc0 [] handle_irq+0x46/0xb0 [] do_IRQ+0x5d/0xe0 [] common_interrupt+0x6e/0x6e [] ? __do_softirq+0x60/0x210 [] ? hrtimer_interrupt+0x151/0x240 [] call_softirq+0x1c/0x30 [] do_softirq+0x65/0xa0 [] irq_exit+0xbd/0xe0 [] smp_apic_timer_interrupt+0x6e/0x99 [] apic_timer_interrupt+0x6e/0x80 [] ? _raw_spin_unlock_irqrestore+0x11/0x20 [] pci_bus_write_config_word+0x6c/0x80 [] pci_intx+0x52/0xa0 [] pci_intx_for_msi+0x1d/0x30 [] pci_msi_shutdown+0x7b/0x110 [] pci_device_shutdown+0x34/0x50 [] device_shutdown+0x2f/0x140 [] kernel_restart_prepare+0x31/0x40 [] kernel_restart+0x16/0x60 [] sys_reboot+0x1ad/0x220 [] ? do_page_fault+0x1e0/0x460 [] ? __sync_filesystem+0x90/0x90 [] ? __cond_resched+0x2a/0x40 [] ? _cond_resched+0x30/0x40 [] ? iterate_supers+0xb7/0xd0 [] system_call_fastpath+0x16/0x1b handlers: [] usb_hcd_irq [] usb_hcd_irq [] usb_hcd_irq Disabling IRQ #16 An un-wanted interrupt is generated when PCI driver switches from MSI/MSI-X to INTx while shutting down the device. The interrupt does not happen if MSI/MSI-X is not used on the device. I confirmed that this problem does not happen if pcie_hp=nomsi was specified and hotplug operation worked fine as usual. v2: Automatically disable MSI/MSI-X against following device: PCI bridge: Integrated Device Technology, Inc. Device 807f (rev 02) v3: Based on the review comment, combile the if statements. v4: Removed module parameter. Move some code to build pciehp as a module. Move device specific code to driver/pci/quirks.c. v5: Drop a device specific code until getting a vendor statement. Reviewed-by: Kenji Kaneshige Signed-off-by: MUNEDA Takahiro Signed-off-by: Jesse Barnes --- Documentation/kernel-parameters.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation/kernel-parameters.txt') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 033d4e69b43b..7fb7a4b161ff 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2118,6 +2118,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. force Enable ASPM even on devices that claim not to support it. WARNING: Forcing ASPM on may cause system lockups. + pcie_hp= [PCIE] PCI Express Hotplug driver options: + nomsi Do not use MSI for PCI Express Native Hotplug (this + makes all PCIe ports use INTx for hotplug services). + pcie_ports= [PCIE] PCIe ports handling: auto Ask the BIOS whether or not to use native PCIe services associated with PCIe ports (PME, hot-plug, AER). Use -- cgit v1.2.3 From b55438fdd5173a367659a7e200acea6c9f77b8cb Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 23 Feb 2012 19:23:30 -0800 Subject: PCI: prepare pci=realloc for multiple options Let the user could enable and disable with pci=realloc=on or pci=realloc=off Also 1. move variable and functions near the place they are used. 2. change macro to function 3. change related functions and variable to static and _init 4. update parameter description accordingly. This will let us add a config option to control default behavior, and still allow the user to turn off automatic reallocation if it fails on their platform until a permanent solution is found. -v2: still honor pci=realloc, and treat it as pci=realloc=on also use enum instead of ... -v3: update kernel-paramenters.txt according to Jesse. Signed-off-by: Yinghai Lu Acked-by: Jesse Barnes Signed-off-by: Jesse Barnes --- Documentation/kernel-parameters.txt | 9 +++++++-- drivers/pci/pci.c | 4 +++- drivers/pci/pci.h | 2 +- drivers/pci/setup-bus.c | 34 +++++++++++++++++++++++++++------- 4 files changed, 38 insertions(+), 11 deletions(-) (limited to 'Documentation/kernel-parameters.txt') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7fb7a4b161ff..7dc523e082a2 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2109,8 +2109,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. the default. off: Turn ECRC off on: Turn ECRC on. - realloc reallocate PCI resources if allocations done by BIOS - are erroneous. + realloc= Enable/disable reallocating PCI bridge resources + if allocations done by BIOS are too small to + accommodate resources required by all child + devices. + off: Turn realloc off + on: Turn realloc on + realloc same as realloc=on pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8f30736dbf3f..e9f9dc183cfc 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3772,8 +3772,10 @@ static int __init pci_setup(char *str) pci_no_msi(); } else if (!strcmp(str, "noaer")) { pci_no_aer(); + } else if (!strncmp(str, "realloc=", 8)) { + pci_realloc_get_opt(str + 8); } else if (!strncmp(str, "realloc", 7)) { - pci_realloc(); + pci_realloc_get_opt("on"); } else if (!strcmp(str, "nodomains")) { pci_no_domains(); } else if (!strncmp(str, "cbiosize=", 9)) { diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 586ac9b097e4..1fc63b39f83f 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -149,7 +149,7 @@ static inline void pci_no_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif -extern void pci_realloc(void); +void pci_realloc_get_opt(char *); static inline int pci_no_d1d2(struct pci_dev *dev) { diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 162edfb356b6..219722df68d6 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -48,13 +48,6 @@ static void free_list(struct list_head *head) } } -int pci_realloc_enable = 0; -#define pci_realloc_enabled() pci_realloc_enable -void pci_realloc(void) -{ - pci_realloc_enable = 1; -} - /** * add_to_list() - add a new resource tracker to the list * @head: Head of the list @@ -1273,6 +1266,33 @@ static int __init pci_get_max_depth(void) return depth; } +/* + * -1: undefined, will auto detect later + * 0: disabled by user + * 1: disabled by auto detect + * 2: enabled by user + * 3: enabled by auto detect + */ +enum enable_type { + undefined = -1, + user_disabled, + auto_disabled, + user_enabled, + auto_enabled, +}; + +static enum enable_type pci_realloc_enable __initdata = undefined; +void __init pci_realloc_get_opt(char *str) +{ + if (!strncmp(str, "off", 3)) + pci_realloc_enable = user_disabled; + else if (!strncmp(str, "on", 2)) + pci_realloc_enable = user_enabled; +} +static bool __init pci_realloc_enabled(void) +{ + return pci_realloc_enable >= user_enabled; +} /* * first try will not touch pci bridge res -- cgit v1.2.3 From 6748dcc269e52925993e0d68447858b41b88b4be Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 1 Mar 2012 00:06:33 +0100 Subject: PCI / PCIe: Introduce command line option to disable ARI There are PCIe devices on the market that report ARI support but then fail to initialize correctly when ARI is actually used. This leads to situations in which kernels 2.6.34 and newer fail to handle systems where the previous kernels worked without any apparent problems. Unfortunately, it is currently unknown how many such devices are there. For this reason, introduce a new kernel command line option, pci=noari, allowing users to disable PCIe ARI altogether if they see problems with PCIe device initialization. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes --- Documentation/kernel-parameters.txt | 1 + drivers/pci/pci.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'Documentation/kernel-parameters.txt') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7dc523e082a2..3d153e5723b4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2116,6 +2116,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. off: Turn realloc off on: Turn realloc on realloc same as realloc=on + noari do not use PCIe ARI. pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b832f0fece97..815674415267 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -94,6 +94,9 @@ u8 pci_cache_line_size; */ unsigned int pcibios_max_latency = 255; +/* If set, the PCIe ARI capability will not be used. */ +static bool pcie_ari_disabled; + /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children * @bus: pointer to PCI bus structure to search @@ -1955,7 +1958,7 @@ void pci_enable_ari(struct pci_dev *dev) u16 flags, ctrl; struct pci_dev *bridge; - if (!pci_is_pcie(dev) || dev->devfn) + if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) return; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); @@ -3840,6 +3843,8 @@ static int __init pci_setup(char *str) pci_realloc_get_opt("on"); } else if (!strcmp(str, "nodomains")) { pci_no_domains(); + } else if (!strncmp(str, "noari", 5)) { + pcie_ari_disabled = true; } else if (!strncmp(str, "cbiosize=", 9)) { pci_cardbus_io_size = memparse(str + 9, &str); } else if (!strncmp(str, "cbmemsize=", 10)) { -- cgit v1.2.3