]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
blk-mq-tag: check for NULL rq when iterating tags
authorJens Axboe <axboe@kernel.dk>
Fri, 19 Jan 2018 12:43:12 +0000 (10:43 -0200)
committerKhalid Elmously <khalid.elmously@canonical.com>
Fri, 16 Feb 2018 17:40:11 +0000 (12:40 -0500)
BugLink: https://bugs.launchpad.net/bugs/1744300
Since we introduced blk-mq-sched, the tags->rqs[] array has been
dynamically assigned. So we need to check for NULL when iterating,
since there's a window of time where the bit is set, but we haven't
dynamically assigned the tags->rqs[] array position yet.

This is perfectly safe, since the memory backing of the request is
never going away while the device is alive.

Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
(cherry-pick from commit 7f5562d5ecc44c757599b201df928ba52fa05047)
Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>
Acked-by: Kamal Mostafa <kamal@canonical.com>
Acked-by: Khalid Elmously <khalid.elmously@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
block/blk-mq-tag.c

index d0be72ccb0914c74fd9140ed112228832752ee6d..dc9e6dac5a2ad51fe899eaf8e0b85f41b42903b3 100644 (file)
@@ -214,7 +214,11 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
                bitnr += tags->nr_reserved_tags;
        rq = tags->rqs[bitnr];
 
-       if (rq->q == hctx->queue)
+       /*
+        * We can hit rq == NULL here, because the tagging functions
+        * test and set the bit before assining ->rqs[].
+        */
+       if (rq && rq->q == hctx->queue)
                iter_data->fn(hctx, rq, iter_data->data, reserved);
        return true;
 }
@@ -248,9 +252,15 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
 
        if (!reserved)
                bitnr += tags->nr_reserved_tags;
+
+       /*
+        * We can hit rq == NULL here, because the tagging functions
+        * test and set the bit before assining ->rqs[].
+        */
        rq = tags->rqs[bitnr];
+       if (rq)
+               iter_data->fn(rq, iter_data->data, reserved);
 
-       iter_data->fn(rq, iter_data->data, reserved);
        return true;
 }