blk-mq: Use proper cpumask iterator
authorThomas Gleixner <tglx@linutronix.de>
Sat, 19 Mar 2016 10:30:33 +0000 (11:30 +0100)
committerJens Axboe <axboe@fb.com>
Sun, 20 Mar 2016 15:34:02 +0000 (09:34 -0600)
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>
block/blk-mq-sysfs.c
block/blk-mq.c
include/linux/blk-mq.h

index 431fdda21737cb91b9a5a0f49fd1c2ccd2cfae7c..4ea4dd8a1eed5a46763fd59f391faad8ff91d3b5 100644 (file)
@@ -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)
index 050f7a13021baca7347df79d8d26dad2b89e327e..1699baf39b78a8379c3cd5559b324d71da41f100 100644 (file)
@@ -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);
index 15a73d49fd1d54a4b401bf3a042b466de6f311c8..9ac9799b702b94617dcbc5842af002030440ccf3 100644 (file)
@@ -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