Tested by: Marco Patalano <[email protected]> On Thu, Aug 2, 2018 at 6:23 AM, Ming Lei <[email protected]> wrote:
> 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: Marco Patalano <[email protected]> > Cc: "Ewan D. Milne" <[email protected]> > Cc: Christoph Hellwig <[email protected]> > Cc: Bart Van Assche <[email protected]> > Cc: Omar Sandoval <[email protected]> > Signed-off-by: Ming Lei <[email protected]> > --- > block/blk-mq-tag.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c > index 09b2ee6694fb..c43b3398d7b4 100644 > --- a/block/blk-mq-tag.c > +++ b/block/blk-mq-tag.c > @@ -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; > -- > 2.9.5 > >
