Skip to content

Commit

Permalink
blk-mq: Use proper cpumask iterator
Browse files Browse the repository at this point in the history
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: Xiong Zhou <jencce.kernel@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
  • Loading branch information
Thomas Gleixner authored and Jens Axboe committed Mar 20, 2016
1 parent 5173cb8 commit 897bb0c
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 17 deletions.
6 changes: 4 additions & 2 deletions block/blk-mq-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct blk_mq_ctx *ctx;
int i;
int cpu;

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);
}
}

int blk_mq_register_disk(struct gendisk *disk)
Expand Down
3 changes: 2 additions & 1 deletion block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1798,11 +1798,12 @@ static void blk_mq_map_swqueue(struct request_queue *q,
/*
* 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 (!cpumask_test_cpu(i, online_mask))
continue;

ctx = per_cpu_ptr(q->queue_ctx, i);
hctx = q->mq_ops->map_queue(q, i);

cpumask_set_cpu(i, hctx->cpumask);
Expand Down
14 changes: 0 additions & 14 deletions include/linux/blk-mq.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,22 +263,8 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq)
for ((i) = 0; (i) < (q)->nr_hw_queues && \
({ 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) \
for ((i) = 0; (i) < (hctx)->nr_ctx && \
({ 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

0 comments on commit 897bb0c

Please sign in to comment.