mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
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:
|
||
|---|---|---|
| .. | ||
| bman_ccsr.c | ||
| bman_portal.c | ||
| bman_priv.h | ||
| bman_test_api.c | ||
| bman_test.c | ||
| bman_test.h | ||
| bman.c | ||
| dpaa_sys.c | ||
| dpaa_sys.h | ||
| Kconfig | ||
| Makefile | ||
| qman_ccsr.c | ||
| qman_portal.c | ||
| qman_priv.h | ||
| qman_test_api.c | ||
| qman_test_stash.c | ||
| qman_test.c | ||
| qman_test.h | ||
| qman.c | ||