Skip to content

Commit

Permalink
blk-mq: move getting driver tag and budget into one helper
Browse files Browse the repository at this point in the history
Move code for getting driver tag and budget into one helper, so
blk_mq_dispatch_rq_list gets a bit simplified, and easier to read.

Meantime move updating of 'no_tag' and 'no_budget_available' into
the branch for handling partial dispatch because that is exactly
consumer of the two local variables.

Also rename the parameter of 'got_budget' as 'ask_budget'.

No functional change.

Signed-off-by: Ming Lei <[email protected]>
Tested-by: Baolin Wang <[email protected]>
Reviewed-by: Sagi Grimberg <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Baolin Wang <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Ming Lei authored and axboe committed Jun 30, 2020
1 parent 445874e commit 7538352
Showing 1 changed file with 40 additions and 26 deletions.
66 changes: 40 additions & 26 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1255,18 +1255,50 @@ static void blk_mq_handle_zone_resource(struct request *rq,
__blk_mq_requeue_request(rq);
}

enum prep_dispatch {
PREP_DISPATCH_OK,
PREP_DISPATCH_NO_TAG,
PREP_DISPATCH_NO_BUDGET,
};

static enum prep_dispatch blk_mq_prep_dispatch_rq(struct request *rq,
bool need_budget)
{
struct blk_mq_hw_ctx *hctx = rq->mq_hctx;

if (need_budget && !blk_mq_get_dispatch_budget(rq->q)) {
blk_mq_put_driver_tag(rq);
return PREP_DISPATCH_NO_BUDGET;
}

if (!blk_mq_get_driver_tag(rq)) {
/*
* The initial allocation attempt failed, so we need to
* rerun the hardware queue when a tag is freed. The
* waitqueue takes care of that. If the queue is run
* before we add this entry back on the dispatch list,
* we'll re-run it below.
*/
if (!blk_mq_mark_tag_wait(hctx, rq)) {
blk_mq_put_dispatch_budget(rq->q);
return PREP_DISPATCH_NO_TAG;
}
}

return PREP_DISPATCH_OK;
}

/*
* Returns true if we did some work AND can potentially do more.
*/
bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
bool got_budget)
{
enum prep_dispatch prep;
struct request_queue *q = hctx->queue;
struct request *rq, *nxt;
bool no_tag = false;
int errors, queued;
blk_status_t ret = BLK_STS_OK;
bool no_budget_avail = false;
LIST_HEAD(zone_list);

if (list_empty(list))
Expand All @@ -1284,31 +1316,9 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
rq = list_first_entry(list, struct request, queuelist);

WARN_ON_ONCE(hctx != rq->mq_hctx);
if (!got_budget && !blk_mq_get_dispatch_budget(q)) {
blk_mq_put_driver_tag(rq);
no_budget_avail = true;
prep = blk_mq_prep_dispatch_rq(rq, !got_budget);
if (prep != PREP_DISPATCH_OK)
break;
}

if (!blk_mq_get_driver_tag(rq)) {
/*
* The initial allocation attempt failed, so we need to
* rerun the hardware queue when a tag is freed. The
* waitqueue takes care of that. If the queue is run
* before we add this entry back on the dispatch list,
* we'll re-run it below.
*/
if (!blk_mq_mark_tag_wait(hctx, rq)) {
blk_mq_put_dispatch_budget(q);
/*
* For non-shared tags, the RESTART check
* will suffice.
*/
if (hctx->flags & BLK_MQ_F_TAG_SHARED)
no_tag = true;
break;
}
}

list_del_init(&rq->queuelist);

Expand Down Expand Up @@ -1361,6 +1371,10 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
*/
if (!list_empty(list)) {
bool needs_restart;
/* For non-shared tags, the RESTART check will suffice */
bool no_tag = prep == PREP_DISPATCH_NO_TAG &&
(hctx->flags & BLK_MQ_F_TAG_SHARED);
bool no_budget_avail = prep == PREP_DISPATCH_NO_BUDGET;

/*
* If we didn't flush the entire list, we could have told
Expand Down

0 comments on commit 7538352

Please sign in to comment.