Skip to content

Commit

Permalink
block: have plug stored requests hold references to the queue
Browse files Browse the repository at this point in the history
Requests that were stored in the cache deliberately didn't hold an enter
reference to the queue, instead we grabbed one every time we pulled a
request out of there. That made for awkward logic on freeing the remainder
of the cached list, if needed, where we had to artificially raise the
queue usage count before each free.

Grab references up front for cached plug requests. That's safer, and also
more efficient.

Fixes: 47c122e ("block: pre-allocate requests if plug is started and is a batch")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Jens Axboe committed Nov 4, 2021
1 parent 3b87c6e commit c5fc7b9
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 4 deletions.
8 changes: 7 additions & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,13 @@ void blk_flush_plug(struct blk_plug *plug, bool from_schedule)
flush_plug_callbacks(plug, from_schedule);
if (!rq_list_empty(plug->mq_list))
blk_mq_flush_plug_list(plug, from_schedule);
if (unlikely(!from_schedule && plug->cached_rq))
/*
* Unconditionally flush out cached requests, even if the unplug
* event came from schedule. Since we know hold references to the
* queue for cached requests, we don't want a blocked task holding
* up a queue freeze/quiesce event.
*/
if (unlikely(!rq_list_empty(plug->cached_rq)))
blk_mq_free_plug_rqs(plug);
}

Expand Down
7 changes: 4 additions & 3 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,10 @@ __blk_mq_alloc_requests_batch(struct blk_mq_alloc_data *data,
tag_mask &= ~(1UL << i);
rq = blk_mq_rq_ctx_init(data, tags, tag, alloc_time_ns);
rq_list_add(data->cached_rq, rq);
nr++;
}
/* caller already holds a reference, add for remainder */
percpu_ref_get_many(&data->q->q_usage_counter, nr - 1);
data->nr_tags -= nr;

return rq_list_pop(data->cached_rq);
Expand Down Expand Up @@ -630,10 +633,8 @@ void blk_mq_free_plug_rqs(struct blk_plug *plug)
{
struct request *rq;

while ((rq = rq_list_pop(&plug->cached_rq)) != NULL) {
percpu_ref_get(&rq->q->q_usage_counter);
while ((rq = rq_list_pop(&plug->cached_rq)) != NULL)
blk_mq_free_request(rq);
}
}

static void req_bio_endio(struct request *rq, struct bio *bio,
Expand Down

0 comments on commit c5fc7b9

Please sign in to comment.