From: Greg Kroah-Hartman Date: Thu, 24 Jan 2013 00:15:31 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.0.61~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=23447c1014d8213e8f43d4ecfe2ec571a2a0589e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch pci-shpchp-handle-push-button-event-asynchronously.patch --- diff --git a/queue-3.4/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch b/queue-3.4/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch new file mode 100644 index 00000000000..c15c2739e6c --- /dev/null +++ b/queue-3.4/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch @@ -0,0 +1,32 @@ +From a82b6af37d20bfe6e99a4d890f1cf1d89059929f Mon Sep 17 00:00:00 2001 +From: Betty Dall +Date: Sun, 13 Jan 2013 15:46:18 -0700 +Subject: PCI/AER: pci_get_domain_bus_and_slot() call missing required pci_dev_put() + +From: Betty Dall + +commit a82b6af37d20bfe6e99a4d890f1cf1d89059929f upstream. + +The function aer_recover_queue() calls pci_get_domain_bus_and_slot(), which +requires that the caller decrement the reference count with pci_dev_put(). +This patch adds the missing call to pci_dev_put(). + +Signed-off-by: Betty Dall +Signed-off-by: Bjorn Helgaas +Reviewed-by: Shuah Khan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pcie/aer/aerdrv_core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pci/pcie/aer/aerdrv_core.c ++++ b/drivers/pci/pcie/aer/aerdrv_core.c +@@ -637,6 +637,7 @@ static void aer_recover_work_func(struct + continue; + } + do_recovery(pdev, entry.severity); ++ pci_dev_put(pdev); + } + } + #endif diff --git a/queue-3.4/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch b/queue-3.4/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch new file mode 100644 index 00000000000..35c5b54044f --- /dev/null +++ b/queue-3.4/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch @@ -0,0 +1,38 @@ +From 9e16721498b0c3d3ebfa0b503c63d35c0a4c0642 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 27 Nov 2012 14:09:40 +0000 +Subject: PCI: Allow pcie_aspm=force even when FADT indicates it is unsupported + +From: Colin Ian King + +commit 9e16721498b0c3d3ebfa0b503c63d35c0a4c0642 upstream. + +Right now using pcie_aspm=force will not enable ASPM if the FADT indicates +ASPM is unsupported. However, the semantics of force should probably allow +for this, especially as they did before 3c076351c4 ("PCI: Rework ASPM +disable code") + +This patch just skips the clearing of any ASPM setup that the firmware has +carried out on this bus if pcie_aspm=force is being used. + +Reference: http://bugs.launchpad.net/bugs/962038 +Signed-off-by: Colin Ian King +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pcie/aspm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -798,6 +798,9 @@ void pcie_clear_aspm(struct pci_bus *bus + { + struct pci_dev *child; + ++ if (aspm_force) ++ return; ++ + /* + * Clear any ASPM setup that the firmware has carried out on this bus + */ diff --git a/queue-3.4/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch b/queue-3.4/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch new file mode 100644 index 00000000000..f45fff35318 --- /dev/null +++ b/queue-3.4/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch @@ -0,0 +1,189 @@ +From c2be6f93b383c873a4f9d521afa49b1b67d06085 Mon Sep 17 00:00:00 2001 +From: Yijing Wang +Date: Fri, 11 Jan 2013 10:15:54 +0800 +Subject: PCI: pciehp: Use per-slot workqueues to avoid deadlock + +From: Yijing Wang + +commit c2be6f93b383c873a4f9d521afa49b1b67d06085 upstream. + +When we have a hotplug-capable PCIe port with a second hotplug-capable +PCIe port below it, removing the device below the upstream port causes +a deadlock. + +The deadlock happens because we use the pciehp_wq workqueue to run +pciehp_power_thread(), which uses pciehp_disable_slot() to remove devices +below the upstream port. When we remove the downstream PCIe port, we call +pciehp_remove(), the pciehp driver's .remove() method. That calls +flush_workqueue(pciehp_wq), which deadlocks because the +pciehp_power_thread() work item is still running. + +This patch avoids the deadlock by creating a workqueue for every PCIe port +and removing the single shared workqueue. + +Here's the call path that leads to the deadlock: + + pciehp_queue_pushbutton_work + queue_work(pciehp_wq) # queue pciehp_power_thread + ... + + pciehp_power_thread + pciehp_disable_slot + remove_board + pciehp_unconfigure_device + pci_stop_and_remove_bus_device + ... + pciehp_remove # pciehp driver .remove method + pciehp_release_ctrl + pcie_cleanup_slot + flush_workqueue(pciehp_wq) + +This is fairly urgent because it can be caused by simply unplugging a +Thunderbolt adapter, as reported by Daniel below. + +[bhelgaas: changelog] +Reference: http://lkml.kernel.org/r/CAMVG2ssiRgcTD1bej2tkUUfsWmpL5eNtPcNif9va2-Gzb2u8nQ@mail.gmail.com +Reported-and-tested-by: Daniel J Blueman +Reviewed-by: Kenji Kaneshige +Signed-off-by: Yijing Wang +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/hotplug/pciehp.h | 2 +- + drivers/pci/hotplug/pciehp_core.c | 11 ++--------- + drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++---- + drivers/pci/hotplug/pciehp_hpc.c | 11 ++++++++++- + 4 files changed, 17 insertions(+), 15 deletions(-) + +--- a/drivers/pci/hotplug/pciehp.h ++++ b/drivers/pci/hotplug/pciehp.h +@@ -44,7 +44,6 @@ extern bool pciehp_poll_mode; + extern int pciehp_poll_time; + extern bool pciehp_debug; + extern bool pciehp_force; +-extern struct workqueue_struct *pciehp_wq; + + #define dbg(format, arg...) \ + do { \ +@@ -78,6 +77,7 @@ struct slot { + struct hotplug_slot *hotplug_slot; + struct delayed_work work; /* work for button event */ + struct mutex lock; ++ struct workqueue_struct *wq; + }; + + struct event_info { +--- a/drivers/pci/hotplug/pciehp_core.c ++++ b/drivers/pci/hotplug/pciehp_core.c +@@ -42,7 +42,6 @@ bool pciehp_debug; + bool pciehp_poll_mode; + int pciehp_poll_time; + bool pciehp_force; +-struct workqueue_struct *pciehp_wq; + + #define DRIVER_VERSION "0.4" + #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " +@@ -340,18 +339,13 @@ static int __init pcied_init(void) + { + int retval = 0; + +- pciehp_wq = alloc_workqueue("pciehp", 0, 0); +- if (!pciehp_wq) +- return -ENOMEM; +- + pciehp_firmware_init(); + retval = pcie_port_service_register(&hpdriver_portdrv); + dbg("pcie_port_service_register = %d\n", retval); + info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); +- if (retval) { +- destroy_workqueue(pciehp_wq); ++ if (retval) + dbg("Failure to register service\n"); +- } ++ + return retval; + } + +@@ -359,7 +353,6 @@ static void __exit pcied_cleanup(void) + { + dbg("unload_pciehpd()\n"); + pcie_port_service_unregister(&hpdriver_portdrv); +- destroy_workqueue(pciehp_wq); + info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); + } + +--- a/drivers/pci/hotplug/pciehp_ctrl.c ++++ b/drivers/pci/hotplug/pciehp_ctrl.c +@@ -49,7 +49,7 @@ static int queue_interrupt_event(struct + info->p_slot = p_slot; + INIT_WORK(&info->work, interrupt_event_handler); + +- queue_work(pciehp_wq, &info->work); ++ queue_work(p_slot->wq, &info->work); + + return 0; + } +@@ -344,7 +344,7 @@ void pciehp_queue_pushbutton_work(struct + kfree(info); + goto out; + } +- queue_work(pciehp_wq, &info->work); ++ queue_work(p_slot->wq, &info->work); + out: + mutex_unlock(&p_slot->lock); + } +@@ -377,7 +377,7 @@ static void handle_button_press_event(st + if (ATTN_LED(ctrl)) + pciehp_set_attention_status(p_slot, 0); + +- queue_delayed_work(pciehp_wq, &p_slot->work, 5*HZ); ++ queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); + break; + case BLINKINGOFF_STATE: + case BLINKINGON_STATE: +@@ -439,7 +439,7 @@ static void handle_surprise_event(struct + else + p_slot->state = POWERON_STATE; + +- queue_work(pciehp_wq, &info->work); ++ queue_work(p_slot->wq, &info->work); + } + + static void interrupt_event_handler(struct work_struct *work) +--- a/drivers/pci/hotplug/pciehp_hpc.c ++++ b/drivers/pci/hotplug/pciehp_hpc.c +@@ -874,23 +874,32 @@ static void pcie_shutdown_notification(s + static int pcie_init_slot(struct controller *ctrl) + { + struct slot *slot; ++ char name[32]; + + slot = kzalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) + return -ENOMEM; + ++ snprintf(name, sizeof(name), "pciehp-%u", PSN(ctrl)); ++ slot->wq = alloc_workqueue(name, 0, 0); ++ if (!slot->wq) ++ goto abort; ++ + slot->ctrl = ctrl; + mutex_init(&slot->lock); + INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); + ctrl->slot = slot; + return 0; ++abort: ++ kfree(slot); ++ return -ENOMEM; + } + + static void pcie_cleanup_slot(struct controller *ctrl) + { + struct slot *slot = ctrl->slot; + cancel_delayed_work(&slot->work); +- flush_workqueue(pciehp_wq); ++ destroy_workqueue(slot->wq); + kfree(slot); + } + diff --git a/queue-3.4/pci-shpchp-handle-push-button-event-asynchronously.patch b/queue-3.4/pci-shpchp-handle-push-button-event-asynchronously.patch new file mode 100644 index 00000000000..8cb9ec6c476 --- /dev/null +++ b/queue-3.4/pci-shpchp-handle-push-button-event-asynchronously.patch @@ -0,0 +1,95 @@ +From d347e75847c1fb299c97736638f45e6ea39702d4 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Fri, 11 Jan 2013 12:07:22 -0700 +Subject: PCI: shpchp: Handle push button event asynchronously + +From: Bjorn Helgaas + +commit d347e75847c1fb299c97736638f45e6ea39702d4 upstream. + +Use non-ordered workqueue for attention button events. + +Attention button events on each slot can be handled asynchronously. So +we should use non-ordered workqueue. This patch also removes ordered +workqueue in shpchp as a result. + +486b10b9f4 ("PCI: pciehp: Handle push button event asynchronously") made +the same change to pciehp. I split this out from a patch by Yijing Wang + so we fix one thing at a time and to make the +shpchp history correspond more closely with the pciehp history. + +Signed-off-by: Bjorn Helgaas +CC: Kenji Kaneshige +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/hotplug/shpchp.h | 1 - + drivers/pci/hotplug/shpchp_core.c | 10 ---------- + drivers/pci/hotplug/shpchp_ctrl.c | 2 +- + 3 files changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/pci/hotplug/shpchp.h ++++ b/drivers/pci/hotplug/shpchp.h +@@ -47,7 +47,6 @@ extern bool shpchp_poll_mode; + extern int shpchp_poll_time; + extern bool shpchp_debug; + extern struct workqueue_struct *shpchp_wq; +-extern struct workqueue_struct *shpchp_ordered_wq; + + #define dbg(format, arg...) \ + do { \ +--- a/drivers/pci/hotplug/shpchp_core.c ++++ b/drivers/pci/hotplug/shpchp_core.c +@@ -40,7 +40,6 @@ bool shpchp_debug; + bool shpchp_poll_mode; + int shpchp_poll_time; + struct workqueue_struct *shpchp_wq; +-struct workqueue_struct *shpchp_ordered_wq; + + #define DRIVER_VERSION "0.4" + #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " +@@ -175,7 +174,6 @@ void cleanup_slots(struct controller *ct + list_del(&slot->slot_list); + cancel_delayed_work(&slot->work); + flush_workqueue(shpchp_wq); +- flush_workqueue(shpchp_ordered_wq); + pci_hp_deregister(slot->hotplug_slot); + } + } +@@ -364,17 +362,10 @@ static int __init shpcd_init(void) + if (!shpchp_wq) + return -ENOMEM; + +- shpchp_ordered_wq = alloc_ordered_workqueue("shpchp_ordered", 0); +- if (!shpchp_ordered_wq) { +- destroy_workqueue(shpchp_wq); +- return -ENOMEM; +- } +- + retval = pci_register_driver(&shpc_driver); + dbg("%s: pci_register_driver = %d\n", __func__, retval); + info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + if (retval) { +- destroy_workqueue(shpchp_ordered_wq); + destroy_workqueue(shpchp_wq); + } + return retval; +@@ -384,7 +375,6 @@ static void __exit shpcd_cleanup(void) + { + dbg("unload_shpchpd()\n"); + pci_unregister_driver(&shpc_driver); +- destroy_workqueue(shpchp_ordered_wq); + destroy_workqueue(shpchp_wq); + info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); + } +--- a/drivers/pci/hotplug/shpchp_ctrl.c ++++ b/drivers/pci/hotplug/shpchp_ctrl.c +@@ -456,7 +456,7 @@ void shpchp_queue_pushbutton_work(struct + kfree(info); + goto out; + } +- queue_work(shpchp_ordered_wq, &info->work); ++ queue_work(shpchp_wq, &info->work); + out: + mutex_unlock(&p_slot->lock); + } diff --git a/queue-3.4/series b/queue-3.4/series index 1d09bd65740..cd51d36b3a0 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -5,3 +5,7 @@ evm-checking-if-removexattr-is-not-a-null.patch ptrace-introduce-signal_wake_up_state-and-ptrace_signal_wake_up.patch ptrace-ensure-arch_ptrace-ptrace_request-can-never-race-with-sigkill.patch wake_up_process-should-be-never-used-to-wakeup-a-task_stopped-traced-task.patch +pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch +pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch +pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch +pci-shpchp-handle-push-button-event-asynchronously.patch