summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2017-08-04 13:37:03 -0600
committerJens Axboe <axboe@kernel.dk>2017-08-09 13:09:08 -0600
commit7f5562d5ecc44c757599b201df928ba52fa05047 (patch)
tree039f673c2bcbb3353756d6907e7c0d9decb556d7 /block
parent62d20aa6a01e13c03f01bc92ba845153cb603299 (diff)
downloadlinux-7f5562d5ecc44c757599b201df928ba52fa05047.tar.gz
linux-7f5562d5ecc44c757599b201df928ba52fa05047.tar.bz2
linux-7f5562d5ecc44c757599b201df928ba52fa05047.zip
blk-mq-tag: check for NULL rq when iterating tags
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>
Diffstat (limited to 'block')
-rw-r--r--block/blk-mq-tag.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index d0be72ccb091..dc9e6dac5a2a 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -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;
}