Commit 897bb0c7 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Jens Axboe

blk-mq: Use proper cpumask iterator

queue_for_each_ctx() iterates over per_cpu variables under the assumption that
the possible cpu mask cannot have holes. That's wrong as all cpumasks can have
holes. In case there are holes the iteration ends up accessing uninitialized
memory and crashing as a result.

Replace the macro by a proper for_each_possible_cpu() loop and drop the unused
macro blk_ctx_sum() which references queue_for_each_ctx().
Reported-by: default avatarXiong Zhou <jencce.kernel@gmail.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 5173cb81
...@@ -416,12 +416,14 @@ void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx) ...@@ -416,12 +416,14 @@ void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx)
static void blk_mq_sysfs_init(struct request_queue *q) static void blk_mq_sysfs_init(struct request_queue *q)
{ {
struct blk_mq_ctx *ctx; struct blk_mq_ctx *ctx;
int i; int cpu;
kobject_init(&q->mq_kobj, &blk_mq_ktype); kobject_init(&q->mq_kobj, &blk_mq_ktype);
queue_for_each_ctx(q, ctx, i) for_each_possible_cpu(cpu) {
ctx = per_cpu_ptr(q->queue_ctx, cpu);
kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
}
} }
int blk_mq_register_disk(struct gendisk *disk) int blk_mq_register_disk(struct gendisk *disk)
......
...@@ -1798,11 +1798,12 @@ static void blk_mq_map_swqueue(struct request_queue *q, ...@@ -1798,11 +1798,12 @@ static void blk_mq_map_swqueue(struct request_queue *q,
/* /*
* Map software to hardware queues * Map software to hardware queues
*/ */
queue_for_each_ctx(q, ctx, i) { for_each_possible_cpu(i) {
/* If the cpu isn't online, the cpu is mapped to first hctx */ /* If the cpu isn't online, the cpu is mapped to first hctx */
if (!cpumask_test_cpu(i, online_mask)) if (!cpumask_test_cpu(i, online_mask))
continue; continue;
ctx = per_cpu_ptr(q->queue_ctx, i);
hctx = q->mq_ops->map_queue(q, i); hctx = q->mq_ops->map_queue(q, i);
cpumask_set_cpu(i, hctx->cpumask); cpumask_set_cpu(i, hctx->cpumask);
......
...@@ -263,22 +263,8 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq) ...@@ -263,22 +263,8 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq)
for ((i) = 0; (i) < (q)->nr_hw_queues && \ for ((i) = 0; (i) < (q)->nr_hw_queues && \
({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++) ({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++)
#define queue_for_each_ctx(q, ctx, i) \
for ((i) = 0; (i) < (q)->nr_queues && \
({ ctx = per_cpu_ptr((q)->queue_ctx, (i)); 1; }); (i)++)
#define hctx_for_each_ctx(hctx, ctx, i) \ #define hctx_for_each_ctx(hctx, ctx, i) \
for ((i) = 0; (i) < (hctx)->nr_ctx && \ for ((i) = 0; (i) < (hctx)->nr_ctx && \
({ ctx = (hctx)->ctxs[(i)]; 1; }); (i)++) ({ ctx = (hctx)->ctxs[(i)]; 1; }); (i)++)
#define blk_ctx_sum(q, sum) \
({ \
struct blk_mq_ctx *__x; \
unsigned int __ret = 0, __i; \
\
queue_for_each_ctx((q), __x, __i) \
__ret += sum; \
__ret; \
})
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment