summaryrefslogtreecommitdiff
path: root/lib/irq_poll.c
diff options
context:
space:
mode:
authorNick Terrell <terrelln@fb.com>2022-12-14 03:21:55 +0300
committerNick Terrell <terrelln@fb.com>2022-12-14 03:21:55 +0300
commit4f2c0a4acffbec01079c28f839422e64ddeff004 (patch)
tree06ada4a8a6d94a94c93944806041b8c994cebfc5 /lib/irq_poll.c
parent88a309465b3f05a100c3b81966982c0f9f5d23a6 (diff)
parent830b3c68c1fb1e9176028d02ef86f3cf76aa2476 (diff)
downloadlinux-4f2c0a4acffbec01079c28f839422e64ddeff004.tar.xz
Merge branch 'main' into zstd-linus
Diffstat (limited to 'lib/irq_poll.c')
-rw-r--r--lib/irq_poll.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/lib/irq_poll.c b/lib/irq_poll.c
index 2f17b488d58e..2d5329a42105 100644
--- a/lib/irq_poll.c
+++ b/lib/irq_poll.c
@@ -188,14 +188,18 @@ EXPORT_SYMBOL(irq_poll_init);
static int irq_poll_cpu_dead(unsigned int cpu)
{
/*
- * If a CPU goes away, splice its entries to the current CPU
- * and trigger a run of the softirq
+ * If a CPU goes away, splice its entries to the current CPU and
+ * set the POLL softirq bit. The local_bh_disable()/enable() pair
+ * ensures that it is handled. Otherwise the current CPU could
+ * reach idle with the POLL softirq pending.
*/
+ local_bh_disable();
local_irq_disable();
list_splice_init(&per_cpu(blk_cpu_iopoll, cpu),
this_cpu_ptr(&blk_cpu_iopoll));
__raise_softirq_irqoff(IRQ_POLL_SOFTIRQ);
local_irq_enable();
+ local_bh_enable();
return 0;
}