diff options
author | Jens Axboe <axboe@kernel.dk> | 2017-08-04 21:37:03 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-08-09 21:09:08 +0200 |
commit | 7f5562d5ecc44c757599b201df928ba52fa05047 (patch) | |
tree | 039f673c2bcbb3353756d6907e7c0d9decb556d7 /block | |
parent | dm-crypt: don't mess with BIP_BLOCK_INTEGRITY (diff) | |
download | linux-7f5562d5ecc44c757599b201df928ba52fa05047.tar.xz 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.c | 14 |
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; } |