diff options
| author | Xiao Liang <shaw.leon@gmail.com> | 2025-10-20 11:37:54 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-10-23 16:16:41 +0200 |
| commit | 6c79b23f1c525f68fdf9b741254f79e61aca75d1 (patch) | |
| tree | cbb61396bf982ae70eacf5ff953ce1d676c315d5 | |
| parent | 5fb3328e927c75d1aed6bf70ded9494c14d5af60 (diff) | |
| download | linux-6c79b23f1c525f68fdf9b741254f79e61aca75d1.tar.gz linux-6c79b23f1c525f68fdf9b741254f79e61aca75d1.tar.bz2 linux-6c79b23f1c525f68fdf9b741254f79e61aca75d1.zip | |
padata: Reset next CPU when reorder sequence wraps around
[ 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 from padata_reorder() function to padata_find_next() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -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 93cd7704ab63..9260ab0b39eb 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); |
