mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-01-07 15:24:53 +00:00
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 <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: stable@vger.kernel.org
|
||
|---|---|---|
| .. | ||
| acpi_pcihp.c | ||
| acpiphp_core.c | ||
| acpiphp_glue.c | ||
| acpiphp_ibm.c | ||
| acpiphp.h | ||
| cpci_hotplug_core.c | ||
| cpci_hotplug_pci.c | ||
| cpci_hotplug.h | ||
| cpcihp_generic.c | ||
| cpcihp_zt5550.c | ||
| cpcihp_zt5550.h | ||
| cpqphp_core.c | ||
| cpqphp_ctrl.c | ||
| cpqphp_nvram.c | ||
| cpqphp_nvram.h | ||
| cpqphp_pci.c | ||
| cpqphp_sysfs.c | ||
| cpqphp.h | ||
| ibmphp_core.c | ||
| ibmphp_ebda.c | ||
| ibmphp_hpc.c | ||
| ibmphp_pci.c | ||
| ibmphp_res.c | ||
| ibmphp.h | ||
| Kconfig | ||
| Makefile | ||
| pci_hotplug_core.c | ||
| pciehp_acpi.c | ||
| pciehp_core.c | ||
| pciehp_ctrl.c | ||
| pciehp_hpc.c | ||
| pciehp_pci.c | ||
| pciehp.h | ||
| pcihp_skeleton.c | ||
| pcihp_slot.c | ||
| rpadlpar_core.c | ||
| rpadlpar_sysfs.c | ||
| rpadlpar.h | ||
| rpaphp_core.c | ||
| rpaphp_pci.c | ||
| rpaphp_slot.c | ||
| rpaphp.h | ||
| s390_pci_hpc.c | ||
| sgi_hotplug.c | ||
| shpchp_core.c | ||
| shpchp_ctrl.c | ||
| shpchp_hpc.c | ||
| shpchp_pci.c | ||
| shpchp_sysfs.c | ||
| shpchp.h | ||