From: Greg Kroah-Hartman Date: Thu, 24 Jan 2013 00:16:00 +0000 (-0800) Subject: 3.7-stable patches X-Git-Tag: v3.0.61~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=905ba7c774d928d1a0d7686b8d56968ea3cec71c;p=thirdparty%2Fkernel%2Fstable-queue.git 3.7-stable patches added patches: alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch alsa-hda-fix-mute-led-for-another-hp-machine.patch arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.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 pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch --- diff --git a/queue-3.7/alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch b/queue-3.7/alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch new file mode 100644 index 00000000000..5121e3cf427 --- /dev/null +++ b/queue-3.7/alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch @@ -0,0 +1,43 @@ +From 42c364ace52ae6b4699105b39f2559c256b6cd4c Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 21 Jan 2013 16:53:37 +0100 +Subject: ALSA: hda - Add Conexant CX20755/20756/20757 codec IDs + +From: Takashi Iwai + +commit 42c364ace52ae6b4699105b39f2559c256b6cd4c upstream. + +These are just compatible with other CX2075x codecs. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_conexant.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -4580,6 +4580,12 @@ static const struct hda_codec_preset snd + .patch = patch_conexant_auto }, + { .id = 0x14f15111, .name = "CX20753/4", + .patch = patch_conexant_auto }, ++ { .id = 0x14f15113, .name = "CX20755", ++ .patch = patch_conexant_auto }, ++ { .id = 0x14f15114, .name = "CX20756", ++ .patch = patch_conexant_auto }, ++ { .id = 0x14f15115, .name = "CX20757", ++ .patch = patch_conexant_auto }, + {} /* terminator */ + }; + +@@ -4603,6 +4609,9 @@ MODULE_ALIAS("snd-hda-codec-id:14f150b9" + MODULE_ALIAS("snd-hda-codec-id:14f1510f"); + MODULE_ALIAS("snd-hda-codec-id:14f15110"); + MODULE_ALIAS("snd-hda-codec-id:14f15111"); ++MODULE_ALIAS("snd-hda-codec-id:14f15113"); ++MODULE_ALIAS("snd-hda-codec-id:14f15114"); ++MODULE_ALIAS("snd-hda-codec-id:14f15115"); + + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("Conexant HD-audio codec"); diff --git a/queue-3.7/alsa-hda-fix-mute-led-for-another-hp-machine.patch b/queue-3.7/alsa-hda-fix-mute-led-for-another-hp-machine.patch new file mode 100644 index 00000000000..a9711adbd08 --- /dev/null +++ b/queue-3.7/alsa-hda-fix-mute-led-for-another-hp-machine.patch @@ -0,0 +1,31 @@ +From e04340375a314166e14519fca9e5b9e9394b2d7a Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Fri, 18 Jan 2013 12:00:47 +0100 +Subject: ALSA: hda - Fix mute led for another HP machine + +From: David Henningsson + +commit e04340375a314166e14519fca9e5b9e9394b2d7a upstream. + +This machine also has the "HP_Mute_LED_0_A" string in DMI information. + +BugLink: https://bugs.launchpad.net/bugs/1096789 +Tested-by: Tammy Yang +Signed-off-by: David Henningsson +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6211,6 +6211,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), + SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x1972, "HP Pavilion 17", ALC269_FIXUP_MIC1_MUTE_LED), ++ SND_PCI_QUIRK(0x103c, 0x1977, "HP Pavilion 14", ALC269_FIXUP_MIC1_MUTE_LED), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), + SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), diff --git a/queue-3.7/arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch b/queue-3.7/arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch new file mode 100644 index 00000000000..7722eb133de --- /dev/null +++ b/queue-3.7/arm64-elf-fix-core-dumping-to-match-what-glibc-expects.patch @@ -0,0 +1,39 @@ +From 9cf2b72b25f3f6a5a1a46a4f36037e66de52465c Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Tue, 22 Jan 2013 15:34:40 +0000 +Subject: arm64: elf: fix core dumping to match what glibc expects + +From: Will Deacon + +commit 9cf2b72b25f3f6a5a1a46a4f36037e66de52465c upstream. + +The kernel's internal definition of ELF_NGREG uses struct pt_regs, which +means that we disagree with userspace on the size of coredumps since +glibc correctly uses the user-visible struct user_pt_regs. + +This patch fixes our ELF_NGREG definition to use struct user_pt_regs +and introduces our own ELF_CORE_COPY_REGS to convert between the user +and kernel structure definitions. + +Signed-off-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/elf.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -26,7 +26,10 @@ + + typedef unsigned long elf_greg_t; + +-#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) ++#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t)) ++#define ELF_CORE_COPY_REGS(dest, regs) \ ++ *(struct user_pt_regs *)&(dest) = (regs)->user_regs; ++ + typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + typedef struct user_fpsimd_state elf_fpregset_t; + diff --git a/queue-3.7/arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch b/queue-3.7/arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch new file mode 100644 index 00000000000..730a5c9a141 --- /dev/null +++ b/queue-3.7/arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch @@ -0,0 +1,48 @@ +From f1b99392caf120d7533da260318fae0eb5053737 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Fri, 18 Jan 2013 19:00:47 +0000 +Subject: arm64: makefile: fix uname munging when setting ARCH on native machine + +From: Will Deacon + +commit f1b99392caf120d7533da260318fae0eb5053737 upstream. + +By popular demand, arch/aarch64 is now known as arch/arm64. However, +uname -m (and indeed the GNU triplet) still use aarch64 as the machine +string. + +This patch fixes native builds of both the kernel and perf tools by +updating the relevant Makefiles to munge the output of uname -m and +set the ARCH variable appropriately. + +Signed-off-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + Makefile | 2 +- + tools/perf/Makefile | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -169,7 +169,7 @@ SUBARCH := $(shell uname -m | sed -e s/i + -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ +- -e s/sh[234].*/sh/ ) ++ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) + + # Cross compiling and selecting different set of gcc/bin-utils + # --------------------------------------------------------------------------- +--- a/tools/perf/Makefile ++++ b/tools/perf/Makefile +@@ -58,7 +58,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e + -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ +- -e s/sh[234].*/sh/ ) ++ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) + NO_PERF_REGS := 1 + + CC = $(CROSS_COMPILE)gcc diff --git a/queue-3.7/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch b/queue-3.7/pci-aer-pci_get_domain_bus_and_slot-call-missing-required-pci_dev_put.patch new file mode 100644 index 00000000000..4e7627a4b4f --- /dev/null +++ b/queue-3.7/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 +@@ -616,6 +616,7 @@ static void aer_recover_work_func(struct + continue; + } + do_recovery(pdev, entry.severity); ++ pci_dev_put(pdev); + } + } + #endif diff --git a/queue-3.7/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch b/queue-3.7/pci-allow-pcie_aspm-force-even-when-fadt-indicates-it-is-unsupported.patch new file mode 100644 index 00000000000..46cfce859c2 --- /dev/null +++ b/queue-3.7/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 +@@ -773,6 +773,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.7/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch b/queue-3.7/pci-pciehp-use-per-slot-workqueues-to-avoid-deadlock.patch new file mode 100644 index 00000000000..2174285890b --- /dev/null +++ b/queue-3.7/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 +@@ -773,23 +773,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.7/pci-shpchp-handle-push-button-event-asynchronously.patch b/queue-3.7/pci-shpchp-handle-push-button-event-asynchronously.patch new file mode 100644 index 00000000000..f9ff955adb5 --- /dev/null +++ b/queue-3.7/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 " +@@ -181,7 +180,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); + } + } +@@ -370,17 +368,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; +@@ -390,7 +381,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 +@@ -453,7 +453,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.7/pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch b/queue-3.7/pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch new file mode 100644 index 00000000000..a3b721721f6 --- /dev/null +++ b/queue-3.7/pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch @@ -0,0 +1,180 @@ +From f652e7d2916fe2fcf9e7d709aa5b7476b431e2dd Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Fri, 11 Jan 2013 12:21:15 -0700 +Subject: PCI: shpchp: Use per-slot workqueues to avoid deadlock + +From: Bjorn Helgaas + +commit f652e7d2916fe2fcf9e7d709aa5b7476b431e2dd upstream. + +When we have an SHPC-capable bridge with a second SHPC-capable bridge +below it, pushing the upstream bridge's attention button causes a +deadlock. + +The deadlock happens because we use the shpchp_wq workqueue to run +shpchp_pushbutton_thread(), which uses shpchp_disable_slot() to remove +devices below the upstream bridge. When we remove the downstream bridge, +we call shpc_remove(), the shpchp driver's .remove() method. That calls +flush_workqueue(shpchp_wq), which deadlocks because the +shpchp_pushbutton_thread() work item is still running. + +This patch avoids the deadlock by creating a workqueue for every slot +and removing the single shared workqueue. + +Here's the call path that leads to the deadlock: + + shpchp_queue_pushbutton_work + queue_work(shpchp_wq) # shpchp_pushbutton_thread + ... + + shpchp_pushbutton_thread + shpchp_disable_slot + remove_board + shpchp_unconfigure_device + pci_stop_and_remove_bus_device + ... + shpc_remove # shpchp driver .remove method + hpc_release_ctlr + cleanup_slots + flush_workqueue(shpchp_wq) + +This change is based on code inspection, since we don't have hardware +with this topology. + +Based-on-patch-by: Yijing Wang +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/hotplug/shpchp.h | 2 +- + drivers/pci/hotplug/shpchp_core.c | 25 +++++++++++++------------ + drivers/pci/hotplug/shpchp_ctrl.c | 6 +++--- + 3 files changed, 17 insertions(+), 16 deletions(-) + +--- a/drivers/pci/hotplug/shpchp.h ++++ b/drivers/pci/hotplug/shpchp.h +@@ -46,7 +46,6 @@ + extern bool shpchp_poll_mode; + extern int shpchp_poll_time; + extern bool shpchp_debug; +-extern struct workqueue_struct *shpchp_wq; + + #define dbg(format, arg...) \ + do { \ +@@ -90,6 +89,7 @@ struct slot { + struct list_head slot_list; + struct delayed_work work; /* work for button event */ + struct mutex lock; ++ struct workqueue_struct *wq; + u8 hp_slot; + }; + +--- a/drivers/pci/hotplug/shpchp_core.c ++++ b/drivers/pci/hotplug/shpchp_core.c +@@ -39,7 +39,6 @@ + bool shpchp_debug; + bool shpchp_poll_mode; + int shpchp_poll_time; +-struct workqueue_struct *shpchp_wq; + + #define DRIVER_VERSION "0.4" + #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " +@@ -128,6 +127,14 @@ static int init_slots(struct controller + slot->device = ctrl->slot_device_offset + i; + slot->hpc_ops = ctrl->hpc_ops; + slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); ++ ++ snprintf(name, sizeof(name), "shpchp-%d", slot->number); ++ slot->wq = alloc_workqueue(name, 0, 0); ++ if (!slot->wq) { ++ retval = -ENOMEM; ++ goto error_info; ++ } ++ + mutex_init(&slot->lock); + INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); + +@@ -147,7 +154,7 @@ static int init_slots(struct controller + if (retval) { + ctrl_err(ctrl, "pci_hp_register failed with error %d\n", + retval); +- goto error_info; ++ goto error_slotwq; + } + + get_power_status(hotplug_slot, &info->power_status); +@@ -159,6 +166,8 @@ static int init_slots(struct controller + } + + return 0; ++error_slotwq: ++ destroy_workqueue(slot->wq); + error_info: + kfree(info); + error_hpslot: +@@ -179,7 +188,7 @@ void cleanup_slots(struct controller *ct + slot = list_entry(tmp, struct slot, slot_list); + list_del(&slot->slot_list); + cancel_delayed_work(&slot->work); +- flush_workqueue(shpchp_wq); ++ destroy_workqueue(slot->wq); + pci_hp_deregister(slot->hotplug_slot); + } + } +@@ -362,18 +371,11 @@ static struct pci_driver shpc_driver = { + + static int __init shpcd_init(void) + { +- int retval = 0; +- +- shpchp_wq = alloc_ordered_workqueue("shpchp", 0); +- if (!shpchp_wq) +- return -ENOMEM; ++ int retval; + + 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_wq); +- } + return retval; + } + +@@ -381,7 +383,6 @@ static void __exit shpcd_cleanup(void) + { + dbg("unload_shpchpd()\n"); + pci_unregister_driver(&shpc_driver); +- 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 +@@ -51,7 +51,7 @@ static int queue_interrupt_event(struct + info->p_slot = p_slot; + INIT_WORK(&info->work, interrupt_event_handler); + +- queue_work(shpchp_wq, &info->work); ++ queue_work(p_slot->wq, &info->work); + + return 0; + } +@@ -453,7 +453,7 @@ void shpchp_queue_pushbutton_work(struct + kfree(info); + goto out; + } +- queue_work(shpchp_wq, &info->work); ++ queue_work(p_slot->wq, &info->work); + out: + mutex_unlock(&p_slot->lock); + } +@@ -501,7 +501,7 @@ static void handle_button_press_event(st + p_slot->hpc_ops->green_led_blink(p_slot); + p_slot->hpc_ops->set_attention_status(p_slot, 0); + +- queue_delayed_work(shpchp_wq, &p_slot->work, 5*HZ); ++ queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ); + break; + case BLINKINGOFF_STATE: + case BLINKINGON_STATE: diff --git a/queue-3.7/series b/queue-3.7/series index fe1bed43869..12bccb51fbb 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -13,3 +13,12 @@ perf-x86-revert-20b279-require-exclude_guest-to-use-pebs-kernel-side.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 +alsa-hda-fix-mute-led-for-another-hp-machine.patch +alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch +arm64-makefile-fix-uname-munging-when-setting-arch-on-native-machine.patch +arm64-elf-fix-core-dumping-to-match-what-glibc-expects.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 +pci-shpchp-use-per-slot-workqueues-to-avoid-deadlock.patch