* [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray
@ 2025-11-27 1:39 Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 1/2] " Fengnan Chang
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Fengnan Chang @ 2025-11-27 1:39 UTC (permalink / raw)
To: axboe, linux-block, ming.lei, hare, hch, yukuai3; +Cc: Fengnan Chang
From: Fengnan Chang <changfengnan@bytedance.com>
After commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray"), we use
an xarray instead of array to store hctx, but in poll mode, each time
in blk_mq_poll, we need use xa_load to find corresponding hctx, this
introduce some costs. In my test, xa_load may cost 3.8% cpu.
After revert previous change, eliminates the overhead of xa_load and can
result in a 3% performance improvement.
potentital use-after-free on q->queue_hw_ctx can be fixed by use rcu to
avoid, same as Yu Kuai did in [1].
[1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
Fengnan Chang (2):
blk-mq: use array manage hctx map instead of xarray
blk-mq: fix potential uaf for 'queue_hw_ctx'
block/blk-mq-tag.c | 2 +-
block/blk-mq.c | 63 ++++++++++++++++++++++++++++--------------
block/blk-mq.h | 13 ++++++++-
include/linux/blk-mq.h | 3 +-
include/linux/blkdev.h | 2 +-
5 files changed, 58 insertions(+), 25 deletions(-)
base-commit: 4941a17751c99e17422be743c02c923ad706f888
--
2.39.5 (Apple Git-154)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/2] blk-mq: use array manage hctx map instead of xarray
2025-11-27 1:39 [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Fengnan Chang
@ 2025-11-27 1:39 ` Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
` (2 subsequent siblings)
3 siblings, 0 replies; 13+ messages in thread
From: Fengnan Chang @ 2025-11-27 1:39 UTC (permalink / raw)
To: axboe, linux-block, ming.lei, hare, hch, yukuai3; +Cc: Fengnan Chang
From: Fengnan Chang <changfengnan@bytedance.com>
After commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray"), we use
an xarray instead of array to store hctx, but in poll mode, each time
in blk_mq_poll, we need use xa_load to find corresponding hctx, this
introduce some costs. In my test, xa_load may cost 3.8% cpu.
This patch revert previous change, eliminates the overhead of xa_load
and can result in a 3% performance improvement.
potential use-after-free on q->queue_hw_ctx can be fixed by use rcu to
avoid in next patch, same as Yu Kuai did in [1].
[1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
---
block/blk-mq-tag.c | 2 +-
block/blk-mq.c | 58 +++++++++++++++++++++++++++---------------
block/blk-mq.h | 2 +-
include/linux/blk-mq.h | 3 ++-
include/linux/blkdev.h | 2 +-
5 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index 5b664dbdf655..33946cdb5716 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -499,7 +499,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_tag_iter_fn *fn,
int srcu_idx;
/*
- * __blk_mq_update_nr_hw_queues() updates nr_hw_queues and hctx_table
+ * __blk_mq_update_nr_hw_queues() updates nr_hw_queues and queue_hw_ctx
* while the queue is frozen. So we can use q_usage_counter to avoid
* racing with it.
*/
diff --git a/block/blk-mq.c b/block/blk-mq.c
index d626d32f6e57..eed12fab3484 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -723,7 +723,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
* If not tell the caller that it should skip this queue.
*/
ret = -EXDEV;
- data.hctx = xa_load(&q->hctx_table, hctx_idx);
+ data.hctx = q->queue_hw_ctx[hctx_idx];
if (!blk_mq_hw_queue_mapped(data.hctx))
goto out_queue_exit;
cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask);
@@ -3935,8 +3935,6 @@ static void blk_mq_exit_hctx(struct request_queue *q,
blk_free_flush_queue_callback);
hctx->fq = NULL;
- xa_erase(&q->hctx_table, hctx_idx);
-
spin_lock(&q->unused_hctx_lock);
list_add(&hctx->hctx_list, &q->unused_hctx_list);
spin_unlock(&q->unused_hctx_lock);
@@ -3978,14 +3976,8 @@ static int blk_mq_init_hctx(struct request_queue *q,
hctx->numa_node))
goto exit_hctx;
- if (xa_insert(&q->hctx_table, hctx_idx, hctx, GFP_KERNEL))
- goto exit_flush_rq;
-
return 0;
- exit_flush_rq:
- if (set->ops->exit_request)
- set->ops->exit_request(set, hctx->fq->flush_rq, hctx_idx);
exit_hctx:
if (set->ops->exit_hctx)
set->ops->exit_hctx(hctx, hctx_idx);
@@ -4374,7 +4366,7 @@ void blk_mq_release(struct request_queue *q)
kobject_put(&hctx->kobj);
}
- xa_destroy(&q->hctx_table);
+ kfree(q->queue_hw_ctx);
/*
* release .mq_kobj and sw queue's kobject now because
@@ -4518,26 +4510,44 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
struct request_queue *q)
{
- struct blk_mq_hw_ctx *hctx;
- unsigned long i, j;
+ int i, j, end;
+ struct blk_mq_hw_ctx **hctxs = q->queue_hw_ctx;
+
+ if (q->nr_hw_queues < set->nr_hw_queues) {
+ struct blk_mq_hw_ctx **new_hctxs;
+
+ new_hctxs = kcalloc_node(set->nr_hw_queues,
+ sizeof(*new_hctxs), GFP_KERNEL,
+ set->numa_node);
+ if (!new_hctxs)
+ return;
+ if (hctxs)
+ memcpy(new_hctxs, hctxs, q->nr_hw_queues *
+ sizeof(*hctxs));
+ q->queue_hw_ctx = new_hctxs;
+ kfree(hctxs);
+ hctxs = new_hctxs;
+ }
for (i = 0; i < set->nr_hw_queues; i++) {
int old_node;
int node = blk_mq_get_hctx_node(set, i);
- struct blk_mq_hw_ctx *old_hctx = xa_load(&q->hctx_table, i);
+ struct blk_mq_hw_ctx *old_hctx = hctxs[i];
if (old_hctx) {
old_node = old_hctx->numa_node;
blk_mq_exit_hctx(q, set, old_hctx, i);
}
- if (!blk_mq_alloc_and_init_hctx(set, q, i, node)) {
+ hctxs[i] = blk_mq_alloc_and_init_hctx(set, q, i, node);
+ if (!hctxs[i]) {
if (!old_hctx)
break;
pr_warn("Allocate new hctx on node %d fails, fallback to previous one on node %d\n",
node, old_node);
- hctx = blk_mq_alloc_and_init_hctx(set, q, i, old_node);
- WARN_ON_ONCE(!hctx);
+ hctxs[i] = blk_mq_alloc_and_init_hctx(set, q, i,
+ old_node);
+ WARN_ON_ONCE(!hctxs[i]);
}
}
/*
@@ -4546,13 +4556,21 @@ static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
*/
if (i != set->nr_hw_queues) {
j = q->nr_hw_queues;
+ end = i;
} else {
j = i;
+ end = q->nr_hw_queues;
q->nr_hw_queues = set->nr_hw_queues;
}
- xa_for_each_start(&q->hctx_table, j, hctx, j)
- blk_mq_exit_hctx(q, set, hctx, j);
+ for (; j < end; j++) {
+ struct blk_mq_hw_ctx *hctx = hctxs[j];
+
+ if (hctx) {
+ blk_mq_exit_hctx(q, set, hctx, j);
+ hctxs[j] = NULL;
+ }
+ }
}
static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
@@ -4588,8 +4606,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
INIT_LIST_HEAD(&q->unused_hctx_list);
spin_lock_init(&q->unused_hctx_lock);
- xa_init(&q->hctx_table);
-
blk_mq_realloc_hw_ctxs(set, q);
if (!q->nr_hw_queues)
goto err_hctxs;
@@ -5168,7 +5184,7 @@ int blk_mq_poll(struct request_queue *q, blk_qc_t cookie,
{
if (!blk_mq_can_poll(q))
return 0;
- return blk_hctx_poll(q, xa_load(&q->hctx_table, cookie), iob, flags);
+ return blk_hctx_poll(q, q->queue_hw_ctx[cookie], iob, flags);
}
int blk_rq_poll(struct request *rq, struct io_comp_batch *iob,
diff --git a/block/blk-mq.h b/block/blk-mq.h
index c4fccdeb5441..80a3f0c2bce7 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -84,7 +84,7 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct request_queue *
enum hctx_type type,
unsigned int cpu)
{
- return xa_load(&q->hctx_table, q->tag_set->map[type].mq_map[cpu]);
+ return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]];
}
static inline enum hctx_type blk_mq_get_hctx_type(blk_opf_t opf)
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index b25d12545f46..0795f29dd65d 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -1000,7 +1000,8 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq)
}
#define queue_for_each_hw_ctx(q, hctx, i) \
- xa_for_each(&(q)->hctx_table, (i), (hctx))
+ for ((i) = 0; (i) < (q)->nr_hw_queues && \
+ ({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++)
#define hctx_for_each_ctx(hctx, ctx, i) \
for ((i) = 0; (i) < (hctx)->nr_ctx && \
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 70b671a9a7f7..56328080ca09 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -493,7 +493,7 @@ struct request_queue {
/* hw dispatch queues */
unsigned int nr_hw_queues;
- struct xarray hctx_table;
+ struct blk_mq_hw_ctx **queue_hw_ctx;
struct percpu_ref q_usage_counter;
struct lock_class_key io_lock_cls_key;
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 1:39 [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 1/2] " Fengnan Chang
@ 2025-11-27 1:39 ` Fengnan Chang
2025-11-27 3:33 ` Ming Lei
` (4 more replies)
2025-11-27 2:47 ` [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Jens Axboe
2025-11-27 2:49 ` Jens Axboe
3 siblings, 5 replies; 13+ messages in thread
From: Fengnan Chang @ 2025-11-27 1:39 UTC (permalink / raw)
To: axboe, linux-block, ming.lei, hare, hch, yukuai3; +Cc: Fengnan Chang
From: Fengnan Chang <changfengnan@bytedance.com>
This is just apply Kuai's patch in [1] with mirror changes.
blk_mq_realloc_hw_ctxs() will free the 'queue_hw_ctx'(e.g. undate
submit_queues through configfs for null_blk), while it might still be
used from other context(e.g. switch elevator to none):
t1 t2
elevator_switch
blk_mq_unquiesce_queue
blk_mq_run_hw_queues
queue_for_each_hw_ctx
// assembly code for hctx = (q)->queue_hw_ctx[i]
mov 0x48(%rbp),%rdx -> read old queue_hw_ctx
__blk_mq_update_nr_hw_queues
blk_mq_realloc_hw_ctxs
hctxs = q->queue_hw_ctx
q->queue_hw_ctx = new_hctxs
kfree(hctxs)
movslq %ebx,%rax
mov (%rdx,%rax,8),%rdi ->uaf
This problem was found by code review, and I comfirmed that the concurrent
scenario do exist(specifically 'q->queue_hw_ctx' can be changed during
blk_mq_run_hw_queues()), however, the uaf problem hasn't been repoduced yet
without hacking the kernel.
Sicne the queue is freezed in __blk_mq_update_nr_hw_queues(), fix the
problem by protecting 'queue_hw_ctx' through rcu where it can be accessed
without grabbing 'q_usage_counter'.
[1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
---
block/blk-mq.c | 7 ++++++-
block/blk-mq.h | 11 +++++++++++
include/linux/blk-mq.h | 2 +-
include/linux/blkdev.h | 2 +-
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index eed12fab3484..0b8b72194003 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -4524,7 +4524,12 @@ static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
if (hctxs)
memcpy(new_hctxs, hctxs, q->nr_hw_queues *
sizeof(*hctxs));
- q->queue_hw_ctx = new_hctxs;
+ rcu_assign_pointer(q->queue_hw_ctx, new_hctxs);
+ /*
+ * Make sure reading the old queue_hw_ctx from other
+ * context concurrently won't trigger uaf.
+ */
+ synchronize_rcu_expedited();
kfree(hctxs);
hctxs = new_hctxs;
}
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 80a3f0c2bce7..52852fab78f0 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -87,6 +87,17 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct request_queue *
return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]];
}
+static inline struct blk_mq_hw_ctx *queue_hctx(struct request_queue *q, int id)
+{
+ struct blk_mq_hw_ctx *hctx;
+
+ rcu_read_lock();
+ hctx = rcu_dereference(q->queue_hw_ctx)[id];
+ rcu_read_unlock();
+
+ return hctx;
+}
+
static inline enum hctx_type blk_mq_get_hctx_type(blk_opf_t opf)
{
enum hctx_type type = HCTX_TYPE_DEFAULT;
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 0795f29dd65d..484baf91fd91 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -1001,7 +1001,7 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq)
#define queue_for_each_hw_ctx(q, hctx, i) \
for ((i) = 0; (i) < (q)->nr_hw_queues && \
- ({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++)
+ ({ hctx = queue_hctx((q), i); 1; }); (i)++)
#define hctx_for_each_ctx(hctx, ctx, i) \
for ((i) = 0; (i) < (hctx)->nr_ctx && \
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 56328080ca09..f50f2d5eeb55 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -493,7 +493,7 @@ struct request_queue {
/* hw dispatch queues */
unsigned int nr_hw_queues;
- struct blk_mq_hw_ctx **queue_hw_ctx;
+ struct blk_mq_hw_ctx __rcu **queue_hw_ctx;
struct percpu_ref q_usage_counter;
struct lock_class_key io_lock_cls_key;
--
2.39.5 (Apple Git-154)
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray
2025-11-27 1:39 [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 1/2] " Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
@ 2025-11-27 2:47 ` Jens Axboe
2025-11-27 2:55 ` fengnan chang
2025-11-27 2:49 ` Jens Axboe
3 siblings, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2025-11-27 2:47 UTC (permalink / raw)
To: Fengnan Chang, linux-block, ming.lei, hare, hch, yukuai3; +Cc: Fengnan Chang
On 11/26/25 6:39 PM, Fengnan Chang wrote:
> From: Fengnan Chang <changfengnan@bytedance.com>
>
> After commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray"), we use
> an xarray instead of array to store hctx, but in poll mode, each time
> in blk_mq_poll, we need use xa_load to find corresponding hctx, this
> introduce some costs. In my test, xa_load may cost 3.8% cpu.
>
> After revert previous change, eliminates the overhead of xa_load and can
> result in a 3% performance improvement.
>
> potentital use-after-free on q->queue_hw_ctx can be fixed by use rcu to
> avoid, same as Yu Kuai did in [1].
>
> [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
What changed in v2? Neither this cover letter nor the patches have any
mention of that.
--
Jens Axboe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray
2025-11-27 1:39 [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Fengnan Chang
` (2 preceding siblings ...)
2025-11-27 2:47 ` [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Jens Axboe
@ 2025-11-27 2:49 ` Jens Axboe
2025-11-27 3:00 ` fengnan chang
3 siblings, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2025-11-27 2:49 UTC (permalink / raw)
To: Fengnan Chang, linux-block, ming.lei, hare, hch; +Cc: Fengnan Chang, Yu Kuai
On 11/26/25 6:39 PM, Fengnan Chang wrote:
> From: Fengnan Chang <changfengnan@bytedance.com>
>
> After commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray"), we use
> an xarray instead of array to store hctx, but in poll mode, each time
> in blk_mq_poll, we need use xa_load to find corresponding hctx, this
> introduce some costs. In my test, xa_load may cost 3.8% cpu.
>
> After revert previous change, eliminates the overhead of xa_load and can
> result in a 3% performance improvement.
>
> potentital use-after-free on q->queue_hw_ctx can be fixed by use rcu to
> avoid, same as Yu Kuai did in [1].
>
> [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
>
> Fengnan Chang (2):
> blk-mq: use array manage hctx map instead of xarray
> blk-mq: fix potential uaf for 'queue_hw_ctx'
>
> block/blk-mq-tag.c | 2 +-
> block/blk-mq.c | 63 ++++++++++++++++++++++++++++--------------
> block/blk-mq.h | 13 ++++++++-
> include/linux/blk-mq.h | 3 +-
> include/linux/blkdev.h | 2 +-
> 5 files changed, 58 insertions(+), 25 deletions(-)
>
>
> base-commit: 4941a17751c99e17422be743c02c923ad706f888
Adding correct Yu address, was also wrong for v1 and somehow not
corrected?
--
Jens Axboe
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray
2025-11-27 2:47 ` [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Jens Axboe
@ 2025-11-27 2:55 ` fengnan chang
0 siblings, 0 replies; 13+ messages in thread
From: fengnan chang @ 2025-11-27 2:55 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block, ming.lei, hare, hch, Fengnan Chang
On Thu, Nov 27, 2025 at 10:47 AM Jens Axboe <axboe@kernel.dk> wrote:
>
> On 11/26/25 6:39 PM, Fengnan Chang wrote:
> > From: Fengnan Chang <changfengnan@bytedance.com>
> >
> > After commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray"), we use
> > an xarray instead of array to store hctx, but in poll mode, each time
> > in blk_mq_poll, we need use xa_load to find corresponding hctx, this
> > introduce some costs. In my test, xa_load may cost 3.8% cpu.
> >
> > After revert previous change, eliminates the overhead of xa_load and can
> > result in a 3% performance improvement.
> >
> > potentital use-after-free on q->queue_hw_ctx can be fixed by use rcu to
> > avoid, same as Yu Kuai did in [1].
> >
> > [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
>
> What changed in v2? Neither this cover letter nor the patches have any
> mention of that.
Sorry for miss change description. Two change in V2:
1. modify synchronize_rcu() to synchronize_rcu_expedited()
2. use rcu_dereference(q->queue_hw_ctx)[id] in queue_hctx to better read.
>
> --
> Jens Axboe
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray
2025-11-27 2:49 ` Jens Axboe
@ 2025-11-27 3:00 ` fengnan chang
0 siblings, 0 replies; 13+ messages in thread
From: fengnan chang @ 2025-11-27 3:00 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block, ming.lei, hare, hch, Fengnan Chang, Yu Kuai
On Thu, Nov 27, 2025 at 10:49 AM Jens Axboe <axboe@kernel.dk> wrote:
>
> On 11/26/25 6:39 PM, Fengnan Chang wrote:
> > From: Fengnan Chang <changfengnan@bytedance.com>
> >
> > After commit 4e5cc99e1e48 ("blk-mq: manage hctx map via xarray"), we use
> > an xarray instead of array to store hctx, but in poll mode, each time
> > in blk_mq_poll, we need use xa_load to find corresponding hctx, this
> > introduce some costs. In my test, xa_load may cost 3.8% cpu.
> >
> > After revert previous change, eliminates the overhead of xa_load and can
> > result in a 3% performance improvement.
> >
> > potentital use-after-free on q->queue_hw_ctx can be fixed by use rcu to
> > avoid, same as Yu Kuai did in [1].
> >
> > [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
> >
> > Fengnan Chang (2):
> > blk-mq: use array manage hctx map instead of xarray
> > blk-mq: fix potential uaf for 'queue_hw_ctx'
> >
> > block/blk-mq-tag.c | 2 +-
> > block/blk-mq.c | 63 ++++++++++++++++++++++++++++--------------
> > block/blk-mq.h | 13 ++++++++-
> > include/linux/blk-mq.h | 3 +-
> > include/linux/blkdev.h | 2 +-
> > 5 files changed, 58 insertions(+), 25 deletions(-)
> >
> >
> > base-commit: 4941a17751c99e17422be743c02c923ad706f888
>
> Adding correct Yu address, was also wrong for v1 and somehow not
> corrected?
I didn't notice this, the error message was blocked in the spam folder.
>
> --
> Jens Axboe
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
@ 2025-11-27 3:33 ` Ming Lei
2025-11-27 3:38 ` Ming Lei
2025-11-27 18:46 ` kernel test robot
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Ming Lei @ 2025-11-27 3:33 UTC (permalink / raw)
To: Fengnan Chang; +Cc: axboe, linux-block, hare, hch, yukuai3, Fengnan Chang
On Thu, Nov 27, 2025 at 09:39:08AM +0800, Fengnan Chang wrote:
> From: Fengnan Chang <changfengnan@bytedance.com>
>
> This is just apply Kuai's patch in [1] with mirror changes.
>
> blk_mq_realloc_hw_ctxs() will free the 'queue_hw_ctx'(e.g. undate
> submit_queues through configfs for null_blk), while it might still be
> used from other context(e.g. switch elevator to none):
>
> t1 t2
> elevator_switch
> blk_mq_unquiesce_queue
> blk_mq_run_hw_queues
> queue_for_each_hw_ctx
> // assembly code for hctx = (q)->queue_hw_ctx[i]
> mov 0x48(%rbp),%rdx -> read old queue_hw_ctx
>
> __blk_mq_update_nr_hw_queues
> blk_mq_realloc_hw_ctxs
> hctxs = q->queue_hw_ctx
> q->queue_hw_ctx = new_hctxs
> kfree(hctxs)
> movslq %ebx,%rax
> mov (%rdx,%rax,8),%rdi ->uaf
>
> This problem was found by code review, and I comfirmed that the concurrent
> scenario do exist(specifically 'q->queue_hw_ctx' can be changed during
> blk_mq_run_hw_queues()), however, the uaf problem hasn't been repoduced yet
> without hacking the kernel.
>
> Sicne the queue is freezed in __blk_mq_update_nr_hw_queues(), fix the
> problem by protecting 'queue_hw_ctx' through rcu where it can be accessed
> without grabbing 'q_usage_counter'.
>
> [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
>
> Signed-off-by: Yu Kuai <yukuai3@huawei.com>
> Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
> ---
> block/blk-mq.c | 7 ++++++-
> block/blk-mq.h | 11 +++++++++++
> include/linux/blk-mq.h | 2 +-
> include/linux/blkdev.h | 2 +-
> 4 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index eed12fab3484..0b8b72194003 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -4524,7 +4524,12 @@ static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
> if (hctxs)
> memcpy(new_hctxs, hctxs, q->nr_hw_queues *
> sizeof(*hctxs));
> - q->queue_hw_ctx = new_hctxs;
> + rcu_assign_pointer(q->queue_hw_ctx, new_hctxs);
> + /*
> + * Make sure reading the old queue_hw_ctx from other
> + * context concurrently won't trigger uaf.
> + */
> + synchronize_rcu_expedited();
> kfree(hctxs);
> hctxs = new_hctxs;
> }
> diff --git a/block/blk-mq.h b/block/blk-mq.h
> index 80a3f0c2bce7..52852fab78f0 100644
> --- a/block/blk-mq.h
> +++ b/block/blk-mq.h
> @@ -87,6 +87,17 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct request_queue *
> return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]];
> }
>
> +static inline struct blk_mq_hw_ctx *queue_hctx(struct request_queue *q, int id)
> +{
> + struct blk_mq_hw_ctx *hctx;
> +
> + rcu_read_lock();
> + hctx = rcu_dereference(q->queue_hw_ctx)[id];
> + rcu_read_unlock();
> +
> + return hctx;
> +}
If `hctx` is retrieved from old table, uaf will be triggered on
`hctx` dereference after returning from queue_hctx().
So rcu read lock should be held anywhere for `hctx` deference.
Thanks,
Ming
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 3:33 ` Ming Lei
@ 2025-11-27 3:38 ` Ming Lei
0 siblings, 0 replies; 13+ messages in thread
From: Ming Lei @ 2025-11-27 3:38 UTC (permalink / raw)
To: Fengnan Chang; +Cc: axboe, linux-block, hare, hch, yukuai3, Fengnan Chang
On Thu, Nov 27, 2025 at 11:33:22AM +0800, Ming Lei wrote:
> On Thu, Nov 27, 2025 at 09:39:08AM +0800, Fengnan Chang wrote:
> > From: Fengnan Chang <changfengnan@bytedance.com>
> >
> > This is just apply Kuai's patch in [1] with mirror changes.
> >
> > blk_mq_realloc_hw_ctxs() will free the 'queue_hw_ctx'(e.g. undate
> > submit_queues through configfs for null_blk), while it might still be
> > used from other context(e.g. switch elevator to none):
> >
> > t1 t2
> > elevator_switch
> > blk_mq_unquiesce_queue
> > blk_mq_run_hw_queues
> > queue_for_each_hw_ctx
> > // assembly code for hctx = (q)->queue_hw_ctx[i]
> > mov 0x48(%rbp),%rdx -> read old queue_hw_ctx
> >
> > __blk_mq_update_nr_hw_queues
> > blk_mq_realloc_hw_ctxs
> > hctxs = q->queue_hw_ctx
> > q->queue_hw_ctx = new_hctxs
> > kfree(hctxs)
> > movslq %ebx,%rax
> > mov (%rdx,%rax,8),%rdi ->uaf
> >
> > This problem was found by code review, and I comfirmed that the concurrent
> > scenario do exist(specifically 'q->queue_hw_ctx' can be changed during
> > blk_mq_run_hw_queues()), however, the uaf problem hasn't been repoduced yet
> > without hacking the kernel.
> >
> > Sicne the queue is freezed in __blk_mq_update_nr_hw_queues(), fix the
> > problem by protecting 'queue_hw_ctx' through rcu where it can be accessed
> > without grabbing 'q_usage_counter'.
> >
> > [1] https://lore.kernel.org/all/20220225072053.2472431-1-yukuai3@huawei.com/
> >
> > Signed-off-by: Yu Kuai <yukuai3@huawei.com>
> > Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
> > ---
> > block/blk-mq.c | 7 ++++++-
> > block/blk-mq.h | 11 +++++++++++
> > include/linux/blk-mq.h | 2 +-
> > include/linux/blkdev.h | 2 +-
> > 4 files changed, 19 insertions(+), 3 deletions(-)
> >
> > diff --git a/block/blk-mq.c b/block/blk-mq.c
> > index eed12fab3484..0b8b72194003 100644
> > --- a/block/blk-mq.c
> > +++ b/block/blk-mq.c
> > @@ -4524,7 +4524,12 @@ static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
> > if (hctxs)
> > memcpy(new_hctxs, hctxs, q->nr_hw_queues *
> > sizeof(*hctxs));
> > - q->queue_hw_ctx = new_hctxs;
> > + rcu_assign_pointer(q->queue_hw_ctx, new_hctxs);
> > + /*
> > + * Make sure reading the old queue_hw_ctx from other
> > + * context concurrently won't trigger uaf.
> > + */
> > + synchronize_rcu_expedited();
> > kfree(hctxs);
> > hctxs = new_hctxs;
> > }
> > diff --git a/block/blk-mq.h b/block/blk-mq.h
> > index 80a3f0c2bce7..52852fab78f0 100644
> > --- a/block/blk-mq.h
> > +++ b/block/blk-mq.h
> > @@ -87,6 +87,17 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue_type(struct request_queue *
> > return q->queue_hw_ctx[q->tag_set->map[type].mq_map[cpu]];
> > }
> >
> > +static inline struct blk_mq_hw_ctx *queue_hctx(struct request_queue *q, int id)
> > +{
> > + struct blk_mq_hw_ctx *hctx;
> > +
> > + rcu_read_lock();
> > + hctx = rcu_dereference(q->queue_hw_ctx)[id];
> > + rcu_read_unlock();
> > +
> > + return hctx;
> > +}
>
>
> If `hctx` is retrieved from old table, uaf will be triggered on
> `hctx` dereference after returning from queue_hctx().
>
> So rcu read lock should be held anywhere for `hctx` deference.
oops, the rcu read lock only protects `q->queue_hw_ctx`, so this
way is fine, sorry for the noise!
Thanks.
Ming
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
2025-11-27 3:33 ` Ming Lei
@ 2025-11-27 18:46 ` kernel test robot
2025-11-27 20:30 ` kernel test robot
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-11-27 18:46 UTC (permalink / raw)
To: Fengnan Chang, axboe, linux-block, ming.lei, hare, hch, yukuai3
Cc: llvm, oe-kbuild-all, Fengnan Chang
Hi Fengnan,
kernel test robot noticed the following build errors:
[auto build test ERROR on 4941a17751c99e17422be743c02c923ad706f888]
url: https://github.com/intel-lab-lkp/linux/commits/Fengnan-Chang/blk-mq-use-array-manage-hctx-map-instead-of-xarray/20251127-094243
base: 4941a17751c99e17422be743c02c923ad706f888
patch link: https://lore.kernel.org/r/20251127013908.66118-3-fengnanchang%40gmail.com
patch subject: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20251128/202511280210.BjxdaKJc-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251128/202511280210.BjxdaKJc-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511280210.BjxdaKJc-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/block/rnbd/rnbd-clt.c:1324:2: error: call to undeclared function 'queue_hctx'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
1324 | queue_for_each_hw_ctx(dev->queue, hctx, i) {
| ^
include/linux/blk-mq.h:1004:17: note: expanded from macro 'queue_for_each_hw_ctx'
1004 | ({ hctx = queue_hctx((q), i); 1; }); (i)++)
| ^
>> drivers/block/rnbd/rnbd-clt.c:1324:2: error: incompatible integer to pointer conversion assigning to 'struct blk_mq_hw_ctx *' from 'int' [-Wint-conversion]
1324 | queue_for_each_hw_ctx(dev->queue, hctx, i) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/blk-mq.h:1004:15: note: expanded from macro 'queue_for_each_hw_ctx'
1004 | ({ hctx = queue_hctx((q), i); 1; }); (i)++)
| ^ ~~~~~~~~~~~~~~~~~~
2 errors generated.
vim +/queue_hctx +1324 drivers/block/rnbd/rnbd-clt.c
f7a7a5c228d45e Jack Wang 2020-05-11 1317
f7a7a5c228d45e Jack Wang 2020-05-11 1318 static void rnbd_init_mq_hw_queues(struct rnbd_clt_dev *dev)
f7a7a5c228d45e Jack Wang 2020-05-11 1319 {
4f481208749a22 Ming Lei 2022-03-08 1320 unsigned long i;
f7a7a5c228d45e Jack Wang 2020-05-11 1321 struct blk_mq_hw_ctx *hctx;
f7a7a5c228d45e Jack Wang 2020-05-11 1322 struct rnbd_queue *q;
f7a7a5c228d45e Jack Wang 2020-05-11 1323
f7a7a5c228d45e Jack Wang 2020-05-11 @1324 queue_for_each_hw_ctx(dev->queue, hctx, i) {
f7a7a5c228d45e Jack Wang 2020-05-11 1325 q = &dev->hw_queues[i];
f7a7a5c228d45e Jack Wang 2020-05-11 1326 rnbd_init_hw_queue(dev, q, hctx);
f7a7a5c228d45e Jack Wang 2020-05-11 1327 hctx->driver_data = q;
f7a7a5c228d45e Jack Wang 2020-05-11 1328 }
f7a7a5c228d45e Jack Wang 2020-05-11 1329 }
f7a7a5c228d45e Jack Wang 2020-05-11 1330
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
2025-11-27 3:33 ` Ming Lei
2025-11-27 18:46 ` kernel test robot
@ 2025-11-27 20:30 ` kernel test robot
2025-11-27 20:41 ` kernel test robot
2025-11-27 23:32 ` kernel test robot
4 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-11-27 20:30 UTC (permalink / raw)
To: Fengnan Chang, axboe, linux-block, ming.lei, hare, hch, yukuai3
Cc: oe-kbuild-all, Fengnan Chang
Hi Fengnan,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 4941a17751c99e17422be743c02c923ad706f888]
url: https://github.com/intel-lab-lkp/linux/commits/Fengnan-Chang/blk-mq-use-array-manage-hctx-map-instead-of-xarray/20251127-094243
base: 4941a17751c99e17422be743c02c923ad706f888
patch link: https://lore.kernel.org/r/20251127013908.66118-3-fengnanchang%40gmail.com
patch subject: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
config: arm64-randconfig-r131-20251128 (https://download.01.org/0day-ci/archive/20251128/202511280340.4LxTSm2A-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251128/202511280340.4LxTSm2A-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511280340.4LxTSm2A-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
block/blk-mq-sysfs.c: note: in included file:
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
--
block/blk-mq-sched.c: note: in included file:
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
--
block/blk-mq-tag.c: note: in included file:
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
--
block/blk-mq-debugfs.c: note: in included file:
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
--
block/kyber-iosched.c: note: in included file (through block/elevator.h):
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
--
block/blk-mq.c:726:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct blk_mq_hw_ctx *hctx @@ got struct blk_mq_hw_ctx [noderef] __rcu * @@
block/blk-mq.c:726:19: sparse: expected struct blk_mq_hw_ctx *hctx
block/blk-mq.c:726:19: sparse: got struct blk_mq_hw_ctx [noderef] __rcu *
block/blk-mq.c:4514:41: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct blk_mq_hw_ctx **hctxs @@ got struct blk_mq_hw_ctx [noderef] __rcu **queue_hw_ctx @@
block/blk-mq.c:4514:41: sparse: expected struct blk_mq_hw_ctx **hctxs
block/blk-mq.c:4514:41: sparse: got struct blk_mq_hw_ctx [noderef] __rcu **queue_hw_ctx
block/blk-mq.c:4527:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.c:4527:17: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.c:4527:17: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.c:5192:48: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct blk_mq_hw_ctx *hctx @@ got struct blk_mq_hw_ctx [noderef] __rcu * @@
block/blk-mq.c:5192:48: sparse: expected struct blk_mq_hw_ctx *hctx
block/blk-mq.c:5192:48: sparse: got struct blk_mq_hw_ctx [noderef] __rcu *
block/blk-mq.c: note: in included file:
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
>> block/blk-mq.h:95:16: sparse: sparse: incompatible types in comparison expression (different address spaces):
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu *[noderef] __rcu *
block/blk-mq.h:95:16: sparse: struct blk_mq_hw_ctx [noderef] __rcu **
vim +95 block/blk-mq.h
89
90 static inline struct blk_mq_hw_ctx *queue_hctx(struct request_queue *q, int id)
91 {
92 struct blk_mq_hw_ctx *hctx;
93
94 rcu_read_lock();
> 95 hctx = rcu_dereference(q->queue_hw_ctx)[id];
96 rcu_read_unlock();
97
98 return hctx;
99 }
100
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
` (2 preceding siblings ...)
2025-11-27 20:30 ` kernel test robot
@ 2025-11-27 20:41 ` kernel test robot
2025-11-27 23:32 ` kernel test robot
4 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-11-27 20:41 UTC (permalink / raw)
To: Fengnan Chang, axboe, linux-block, ming.lei, hare, hch, yukuai3
Cc: oe-kbuild-all, Fengnan Chang
Hi Fengnan,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 4941a17751c99e17422be743c02c923ad706f888]
url: https://github.com/intel-lab-lkp/linux/commits/Fengnan-Chang/blk-mq-use-array-manage-hctx-map-instead-of-xarray/20251127-094243
base: 4941a17751c99e17422be743c02c923ad706f888
patch link: https://lore.kernel.org/r/20251127013908.66118-3-fengnanchang%40gmail.com
patch subject: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
config: arm-randconfig-002-20251128 (https://download.01.org/0day-ci/archive/20251128/202511280407.DzqlGFFg-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251128/202511280407.DzqlGFFg-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511280407.DzqlGFFg-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/block/rnbd/rnbd-clt.h:16,
from drivers/block/rnbd/rnbd-clt.c:19:
drivers/block/rnbd/rnbd-clt.c: In function 'rnbd_init_mq_hw_queues':
include/linux/blk-mq.h:1004:17: error: implicit declaration of function 'queue_hctx'; did you mean 'queue_work'? [-Werror=implicit-function-declaration]
({ hctx = queue_hctx((q), i); 1; }); (i)++)
^~~~~~~~~~
drivers/block/rnbd/rnbd-clt.c:1324:2: note: in expansion of macro 'queue_for_each_hw_ctx'
queue_for_each_hw_ctx(dev->queue, hctx, i) {
^~~~~~~~~~~~~~~~~~~~~
>> include/linux/blk-mq.h:1004:15: warning: assignment to 'struct blk_mq_hw_ctx *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
({ hctx = queue_hctx((q), i); 1; }); (i)++)
^
drivers/block/rnbd/rnbd-clt.c:1324:2: note: in expansion of macro 'queue_for_each_hw_ctx'
queue_for_each_hw_ctx(dev->queue, hctx, i) {
^~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from rnbd-clt.h:16,
from rnbd-clt.c:19:
rnbd-clt.c: In function 'rnbd_init_mq_hw_queues':
include/linux/blk-mq.h:1004:17: error: implicit declaration of function 'queue_hctx'; did you mean 'queue_work'? [-Werror=implicit-function-declaration]
({ hctx = queue_hctx((q), i); 1; }); (i)++)
^~~~~~~~~~
rnbd-clt.c:1324:2: note: in expansion of macro 'queue_for_each_hw_ctx'
queue_for_each_hw_ctx(dev->queue, hctx, i) {
^~~~~~~~~~~~~~~~~~~~~
>> include/linux/blk-mq.h:1004:15: warning: assignment to 'struct blk_mq_hw_ctx *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
({ hctx = queue_hctx((q), i); 1; }); (i)++)
^
rnbd-clt.c:1324:2: note: in expansion of macro 'queue_for_each_hw_ctx'
queue_for_each_hw_ctx(dev->queue, hctx, i) {
^~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +1004 include/linux/blk-mq.h
1001
1002 #define queue_for_each_hw_ctx(q, hctx, i) \
1003 for ((i) = 0; (i) < (q)->nr_hw_queues && \
> 1004 ({ hctx = queue_hctx((q), i); 1; }); (i)++)
1005
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
` (3 preceding siblings ...)
2025-11-27 20:41 ` kernel test robot
@ 2025-11-27 23:32 ` kernel test robot
4 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-11-27 23:32 UTC (permalink / raw)
To: Fengnan Chang, axboe, linux-block, ming.lei, hare, hch, yukuai3
Cc: oe-kbuild-all, Fengnan Chang
Hi Fengnan,
kernel test robot noticed the following build errors:
[auto build test ERROR on 4941a17751c99e17422be743c02c923ad706f888]
url: https://github.com/intel-lab-lkp/linux/commits/Fengnan-Chang/blk-mq-use-array-manage-hctx-map-instead-of-xarray/20251127-094243
base: 4941a17751c99e17422be743c02c923ad706f888
patch link: https://lore.kernel.org/r/20251127013908.66118-3-fengnanchang%40gmail.com
patch subject: [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx'
config: um-allyesconfig (https://download.01.org/0day-ci/archive/20251128/202511280714.MCsRsCmR-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251128/202511280714.MCsRsCmR-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511280714.MCsRsCmR-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/block/rnbd/rnbd-clt.h:16,
from drivers/block/rnbd/rnbd-clt.c:19:
drivers/block/rnbd/rnbd-clt.c: In function 'rnbd_init_mq_hw_queues':
>> include/linux/blk-mq.h:1004:24: error: implicit declaration of function 'queue_hctx' [-Wimplicit-function-declaration]
1004 | ({ hctx = queue_hctx((q), i); 1; }); (i)++)
| ^~~~~~~~~~
drivers/block/rnbd/rnbd-clt.c:1324:9: note: in expansion of macro 'queue_for_each_hw_ctx'
1324 | queue_for_each_hw_ctx(dev->queue, hctx, i) {
| ^~~~~~~~~~~~~~~~~~~~~
>> include/linux/blk-mq.h:1004:22: error: assignment to 'struct blk_mq_hw_ctx *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
1004 | ({ hctx = queue_hctx((q), i); 1; }); (i)++)
| ^
drivers/block/rnbd/rnbd-clt.c:1324:9: note: in expansion of macro 'queue_for_each_hw_ctx'
1324 | queue_for_each_hw_ctx(dev->queue, hctx, i) {
| ^~~~~~~~~~~~~~~~~~~~~
vim +/queue_hctx +1004 include/linux/blk-mq.h
1001
1002 #define queue_for_each_hw_ctx(q, hctx, i) \
1003 for ((i) = 0; (i) < (q)->nr_hw_queues && \
> 1004 ({ hctx = queue_hctx((q), i); 1; }); (i)++)
1005
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-11-27 23:33 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-27 1:39 [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 1/2] " Fengnan Chang
2025-11-27 1:39 ` [PATCH v2 2/2] blk-mq: fix potential uaf for 'queue_hw_ctx' Fengnan Chang
2025-11-27 3:33 ` Ming Lei
2025-11-27 3:38 ` Ming Lei
2025-11-27 18:46 ` kernel test robot
2025-11-27 20:30 ` kernel test robot
2025-11-27 20:41 ` kernel test robot
2025-11-27 23:32 ` kernel test robot
2025-11-27 2:47 ` [PATCH v2 0/2] blk-mq: use array manage hctx map instead of xarray Jens Axboe
2025-11-27 2:55 ` fengnan chang
2025-11-27 2:49 ` Jens Axboe
2025-11-27 3:00 ` fengnan chang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).