From: Xiao Liang shaw.leon@gmail.com
[ Upstream commit 501302d5cee0d8e8ec2c4a5919c37e0df9abc99b ]
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 [ relocated fix to padata_find_next() using pd->processed and pd->cpu structure fields ] Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/padata.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/padata.c b/kernel/padata.c index 3e0ef0753e73e..c3810f5bd7156 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -290,7 +290,11 @@ static struct padata_priv *padata_find_next(struct parallel_data *pd, if (remove_object) { list_del_init(&padata->list); ++pd->processed; - pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, false); + /* When sequence wraps around, reset to the first CPU. */ + if (unlikely(pd->processed == 0)) + pd->cpu = cpumask_first(pd->cpumask.pcpu); + else + pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, false); }
spin_unlock(&reorder->lock);