diff options
| author | Richard Genoud <richard.genoud@bootlin.com> | 2025-12-23 08:25:49 +0100 |
|---|---|---|
| committer | Christophe Leroy (CS GROUP) <chleroy@kernel.org> | 2026-02-23 14:49:27 +0100 |
| commit | 014077044e874e270ec480515edbc1cadb976cf2 (patch) | |
| tree | a63d1e937ed5d66422ee8d01702eed499765ec7c /include/uapi/linux | |
| parent | 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f (diff) | |
soc: fsl: qbman: fix race condition in qman_destroy_fq
When QMAN_FQ_FLAG_DYNAMIC_FQID is set, there's a race condition between
fq_table[fq->idx] state and freeing/allocating from the pool and
WARN_ON(fq_table[fq->idx]) in qman_create_fq() gets triggered.
Indeed, we can have:
Thread A Thread B
qman_destroy_fq() qman_create_fq()
qman_release_fqid()
qman_shutdown_fq()
gen_pool_free()
-- At this point, the fqid is available again --
qman_alloc_fqid()
-- so, we can get the just-freed fqid in thread B --
fq->fqid = fqid;
fq->idx = fqid * 2;
WARN_ON(fq_table[fq->idx]);
fq_table[fq->idx] = fq;
fq_table[fq->idx] = NULL;
And adding some logs between qman_release_fqid() and
fq_table[fq->idx] = NULL makes the WARN_ON() trigger a lot more.
To prevent that, ensure that fq_table[fq->idx] is set to NULL before
gen_pool_free() is called by using smp_wmb().
Fixes: c535e923bb97 ("soc/fsl: Introduce DPAA 1.x QMan device driver")
Signed-off-by: Richard Genoud <richard.genoud@bootlin.com>
Tested-by: CHAMPSEIX Thomas <thomas.champseix@alstomgroup.com>
Link: https://lore.kernel.org/r/20251223072549.397625-1-richard.genoud@bootlin.com
Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Diffstat (limited to 'include/uapi/linux')
0 files changed, 0 insertions, 0 deletions
