diff options
| author | Xiao Liang <shaw.leon@gmail.com> | 2025-08-17 00:30:15 +0800 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2025-08-22 17:28:44 +0800 |
| commit | 501302d5cee0d8e8ec2c4a5919c37e0df9abc99b (patch) | |
| tree | 1685b9f26eb6adc059c6411da9dfe6ed112419b4 /kernel/padata.c | |
| parent | 56a50e37fee038d004866e5a2c479706d6034017 (diff) | |
padata: Reset next CPU when reorder sequence wraps around
When seq_nr wraps around, the next reorder job with seq 0 is hashed to
the first CPU in padata_do_serial(). Correspondingly, need reset pd->cpu
to the first one when pd->processed wraps around. Otherwise, if the
number of used CPUs is not a power of 2, padata_find_next() will be
checking a wrong list, hence deadlock.
Fixes: 6fc4dbcf0276 ("padata: Replace delayed timer with immediate workqueue in padata_reorder")
Cc: <stable@vger.kernel.org>
Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'kernel/padata.c')
| -rw-r--r-- | kernel/padata.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/padata.c b/kernel/padata.c index f85f8bd788d0..833740d75483 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -291,8 +291,12 @@ static void padata_reorder(struct padata_priv *padata) struct padata_serial_queue *squeue; int cb_cpu; - cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu); processed++; + /* When sequence wraps around, reset to the first CPU. */ + if (unlikely(processed == 0)) + cpu = cpumask_first(pd->cpumask.pcpu); + else + cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu); cb_cpu = padata->cb_cpu; squeue = per_cpu_ptr(pd->squeue, cb_cpu); |