aboutsummaryrefslogtreecommitdiff
path: root/lib/bug.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2013-01-11 12:21:15 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-07 16:02:07 -0700
commit51a937d48eee52b33ba1f2feb2b8b40d254800c9 (patch)
tree3f24fefc522702d7c78cac8953fae76a44cbb078 /lib/bug.c
parent3a2c0d4b76454fe93fa4a5042962cfd76a0a31e2 (diff)
PCI: shpchp: Use per-slot workqueues to avoid deadlock
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 <wangyijing@huawei.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> [hq: Backported to 3.4: adjust context] Signed-off-by: Qiang Huang <h.huangqiang@huawei.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'lib/bug.c')
0 files changed, 0 insertions, 0 deletions