blk-mq: fix updating tags depth
authorMing Lei <[email protected]>
Thu, 2 Aug 2018 10:23:26 +0000 (18:23 +0800)
committerJens Axboe <[email protected]>
Thu, 2 Aug 2018 20:41:58 +0000 (14:41 -0600)
The passed 'nr' from userspace represents the total depth, meantime
inside 'struct blk_mq_tags', 'nr_tags' stores the total tag depth,
and 'nr_reserved_tags' stores the reserved part.

There are two issues in blk_mq_tag_update_depth() now:

1) for growing tags, we should have used the passed 'nr', and keep the
number of reserved tags not changed.

2) the passed 'nr' should have been used for checking against
'tags->nr_tags', instead of number of the normal part.

This patch fixes the above two cases, and avoids kernel crash caused
by wrong resizing sbitmap queue.

Cc: "Ewan D. Milne" <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Bart Van Assche <[email protected]>
Cc: Omar Sandoval <[email protected]>
Tested by: Marco Patalano <[email protected]>
Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
block/blk-mq-tag.c

index 09b2ee6694fb16858a104b7021b986aff603a91a..c43b3398d7b417f9a6890410a948b7079b5caeba 100644 (file)
@@ -399,8 +399,6 @@ int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx,
        if (tdepth <= tags->nr_reserved_tags)
                return -EINVAL;
 
-       tdepth -= tags->nr_reserved_tags;
-
        /*
         * If we are allowed to grow beyond the original size, allocate
         * a new set of tags before freeing the old one.
@@ -420,7 +418,8 @@ int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx,
                if (tdepth > 16 * BLKDEV_MAX_RQ)
                        return -EINVAL;
 
-               new = blk_mq_alloc_rq_map(set, hctx->queue_num, tdepth, 0);
+               new = blk_mq_alloc_rq_map(set, hctx->queue_num, tdepth,
+                               tags->nr_reserved_tags);
                if (!new)
                        return -ENOMEM;
                ret = blk_mq_alloc_rqs(set, new, hctx->queue_num, tdepth);
@@ -437,7 +436,8 @@ int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx,
                 * Don't need (or can't) update reserved tags here, they
                 * remain static and should never need resizing.
                 */
-               sbitmap_queue_resize(&tags->bitmap_tags, tdepth);
+               sbitmap_queue_resize(&tags->bitmap_tags,
+                               tdepth - tags->nr_reserved_tags);
        }
 
        return 0;