block: Improve zone write request completion handling

blk_zone_complete_request() must be called to handle the completion of a
zone write request handled with zone write plugging. This function is
called from blk_complete_request(), blk_update_request() and also in
blk_mq_submit_bio() error path. Improve this by moving this function
call into blk_mq_finish_request() as all requests are processed with
this function when they complete as well as when they are freed without
being executed. This also improves blk_update_request() used by scsi
devices as these may repeatedly call this function to handle partial
completions.

To be consistent with this change, blk_zone_complete_request() is
renamed to blk_zone_finish_request() and
blk_zone_write_plug_complete_request() is renamed to
blk_zone_write_plug_finish_request().

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://lore.kernel.org/r/20240501110907.96950-12-dlemoal@kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Damien Le Moal 2024-05-01 20:09:04 +09:00 committed by Jens Axboe
parent c4c3ffdab2
commit 347bde9da1
3 changed files with 12 additions and 13 deletions

View file

@ -691,6 +691,8 @@ static void blk_mq_finish_request(struct request *rq)
{ {
struct request_queue *q = rq->q; struct request_queue *q = rq->q;
blk_zone_finish_request(rq);
if (rq->rq_flags & RQF_USE_SCHED) { if (rq->rq_flags & RQF_USE_SCHED) {
q->elevator->type->ops.finish_request(rq); q->elevator->type->ops.finish_request(rq);
/* /*
@ -828,8 +830,6 @@ static void blk_complete_request(struct request *req)
bio = next; bio = next;
} while (bio); } while (bio);
blk_zone_complete_request(req);
/* /*
* Reset counters so that the request stacking driver * Reset counters so that the request stacking driver
* can find how many bytes remain in the request * can find how many bytes remain in the request
@ -940,7 +940,6 @@ bool blk_update_request(struct request *req, blk_status_t error,
* completely done * completely done
*/ */
if (!req->bio) { if (!req->bio) {
blk_zone_complete_request(req);
/* /*
* Reset counters so that the request stacking driver * Reset counters so that the request stacking driver
* can find how many bytes remain in the request * can find how many bytes remain in the request
@ -2996,7 +2995,6 @@ void blk_mq_submit_bio(struct bio *bio)
if (ret != BLK_STS_OK) { if (ret != BLK_STS_OK) {
bio->bi_status = ret; bio->bi_status = ret;
bio_endio(bio); bio_endio(bio);
blk_zone_complete_request(rq);
blk_mq_free_request(rq); blk_mq_free_request(rq);
return; return;
} }

View file

@ -531,7 +531,7 @@ static inline bool disk_should_remove_zone_wplug(struct gendisk *disk,
/* /*
* Completions of BIOs with blk_zone_write_plug_bio_endio() may * Completions of BIOs with blk_zone_write_plug_bio_endio() may
* happen after handling a request completion with * happen after handling a request completion with
* blk_zone_write_plug_complete_request() (e.g. with split BIOs * blk_zone_write_plug_finish_request() (e.g. with split BIOs
* that are chained). In such case, disk_zone_wplug_unplug_bio() * that are chained). In such case, disk_zone_wplug_unplug_bio()
* should not attempt to remove the zone write plug until all BIO * should not attempt to remove the zone write plug until all BIO
* completions are seen. Check by looking at the zone write plug * completions are seen. Check by looking at the zone write plug
@ -921,7 +921,7 @@ void blk_zone_write_plug_init_request(struct request *req)
/* /*
* Indicate that completion of this request needs to be handled with * Indicate that completion of this request needs to be handled with
* blk_zone_write_plug_complete_request(), which will drop the reference * blk_zone_write_plug_finish_request(), which will drop the reference
* on the zone write plug we took above on entry to this function. * on the zone write plug we took above on entry to this function.
*/ */
req->rq_flags |= RQF_ZONE_WRITE_PLUGGING; req->rq_flags |= RQF_ZONE_WRITE_PLUGGING;
@ -1255,7 +1255,7 @@ void blk_zone_write_plug_bio_endio(struct bio *bio)
disk_put_zone_wplug(zwplug); disk_put_zone_wplug(zwplug);
/* /*
* For BIO-based devices, blk_zone_write_plug_complete_request() * For BIO-based devices, blk_zone_write_plug_finish_request()
* is not called. So we need to schedule execution of the next * is not called. So we need to schedule execution of the next
* plugged BIO here. * plugged BIO here.
*/ */
@ -1266,11 +1266,12 @@ void blk_zone_write_plug_bio_endio(struct bio *bio)
disk_put_zone_wplug(zwplug); disk_put_zone_wplug(zwplug);
} }
void blk_zone_write_plug_complete_request(struct request *req) void blk_zone_write_plug_finish_request(struct request *req)
{ {
struct gendisk *disk = req->q->disk; struct gendisk *disk = req->q->disk;
struct blk_zone_wplug *zwplug = disk_get_zone_wplug(disk, req->__sector); struct blk_zone_wplug *zwplug;
zwplug = disk_get_zone_wplug(disk, req->__sector);
if (WARN_ON_ONCE(!zwplug)) if (WARN_ON_ONCE(!zwplug))
return; return;

View file

@ -453,11 +453,11 @@ static inline void blk_zone_bio_endio(struct bio *bio)
blk_zone_write_plug_bio_endio(bio); blk_zone_write_plug_bio_endio(bio);
} }
void blk_zone_write_plug_complete_request(struct request *rq); void blk_zone_write_plug_finish_request(struct request *rq);
static inline void blk_zone_complete_request(struct request *rq) static inline void blk_zone_finish_request(struct request *rq)
{ {
if (rq->rq_flags & RQF_ZONE_WRITE_PLUGGING) if (rq->rq_flags & RQF_ZONE_WRITE_PLUGGING)
blk_zone_write_plug_complete_request(rq); blk_zone_write_plug_finish_request(rq);
} }
int blkdev_report_zones_ioctl(struct block_device *bdev, unsigned int cmd, int blkdev_report_zones_ioctl(struct block_device *bdev, unsigned int cmd,
unsigned long arg); unsigned long arg);
@ -491,7 +491,7 @@ static inline void blk_zone_update_request_bio(struct request *rq,
static inline void blk_zone_bio_endio(struct bio *bio) static inline void blk_zone_bio_endio(struct bio *bio)
{ {
} }
static inline void blk_zone_complete_request(struct request *rq) static inline void blk_zone_finish_request(struct request *rq)
{ {
} }
static inline int blkdev_report_zones_ioctl(struct block_device *bdev, static inline int blkdev_report_zones_ioctl(struct block_device *bdev,