Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

blk-mq: check invalid nr_requests in queue_requests_store()

queue_requests_store() is the only caller of
blk_mq_update_nr_requests(), and blk_mq_update_nr_requests() is the
only caller of blk_mq_tag_update_depth(), however, they all have
checkings for nr_requests input by user.

Make code cleaner by moving all the checkings to the top function:

1) nr_requests > reserved tags;
2) if there is elevator, 4 <= nr_requests <= 2048;
3) if elevator is none, 4 <= nr_requests <= tag_set->queue_depth;

Meanwhile, case 2 is the only case tags can grow and -ENOMEM might be
returned.

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Yu Kuai and committed by
Jens Axboe
b46d4c44 8bd7195f

+17 -22
+1 -15
block/blk-mq-tag.c
··· 610 610 } 611 611 612 612 int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx, 613 - struct blk_mq_tags **tagsptr, unsigned int tdepth, 614 - bool can_grow) 613 + struct blk_mq_tags **tagsptr, unsigned int tdepth) 615 614 { 616 615 struct blk_mq_tags *tags = *tagsptr; 617 - 618 - if (tdepth <= tags->nr_reserved_tags) 619 - return -EINVAL; 620 616 621 617 /* 622 618 * If we are allowed to grow beyond the original size, allocate ··· 621 625 if (tdepth > tags->nr_tags) { 622 626 struct blk_mq_tag_set *set = hctx->queue->tag_set; 623 627 struct blk_mq_tags *new; 624 - 625 - if (!can_grow) 626 - return -EINVAL; 627 - 628 - /* 629 - * We need some sort of upper limit, set it high enough that 630 - * no valid use cases should require more. 631 - */ 632 - if (tdepth > MAX_SCHED_RQ) 633 - return -EINVAL; 634 628 635 629 /* 636 630 * Only the sbitmap needs resizing since we allocated the max
+2 -6
block/blk-mq.c
··· 4933 4933 int ret = 0; 4934 4934 unsigned long i; 4935 4935 4936 - if (q->nr_requests == nr) 4937 - return 0; 4938 - 4939 4936 blk_mq_quiesce_queue(q); 4940 4937 4941 4938 queue_for_each_hw_ctx(q, hctx, i) { ··· 4944 4947 */ 4945 4948 if (hctx->sched_tags) { 4946 4949 ret = blk_mq_tag_update_depth(hctx, &hctx->sched_tags, 4947 - nr, true); 4950 + nr); 4948 4951 } else { 4949 - ret = blk_mq_tag_update_depth(hctx, &hctx->tags, nr, 4950 - false); 4952 + ret = blk_mq_tag_update_depth(hctx, &hctx->tags, nr); 4951 4953 } 4952 4954 if (ret) 4953 4955 goto out;
+1 -1
block/blk-mq.h
··· 171 171 unsigned int tag); 172 172 void blk_mq_put_tags(struct blk_mq_tags *tags, int *tag_array, int nr_tags); 173 173 int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx, 174 - struct blk_mq_tags **tags, unsigned int depth, bool can_grow); 174 + struct blk_mq_tags **tags, unsigned int depth); 175 175 void blk_mq_tag_resize_shared_tags(struct blk_mq_tag_set *set, 176 176 unsigned int size); 177 177 void blk_mq_tag_update_sched_shared_tags(struct request_queue *q);
+13
block/blk-sysfs.c
··· 75 75 76 76 memflags = blk_mq_freeze_queue(q); 77 77 mutex_lock(&q->elevator_lock); 78 + 79 + if (nr == q->nr_requests) 80 + goto unlock; 81 + 78 82 if (nr < BLKDEV_MIN_RQ) 79 83 nr = BLKDEV_MIN_RQ; 84 + 85 + if (nr <= q->tag_set->reserved_tags || 86 + (q->elevator && nr > MAX_SCHED_RQ) || 87 + (!q->elevator && nr > q->tag_set->queue_depth)) { 88 + ret = -EINVAL; 89 + goto unlock; 90 + } 80 91 81 92 err = blk_mq_update_nr_requests(disk->queue, nr); 82 93 if (err) 83 94 ret = err; 95 + 96 + unlock: 84 97 mutex_unlock(&q->elevator_lock); 85 98 blk_mq_unfreeze_queue(q, memflags); 86 99 return ret;