diff options
author | Christoph Hellwig <hch@lst.de> | 2023-05-19 06:40:45 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2023-05-19 19:52:29 -0600 |
commit | c1075e548ce6e6b5c7b71f2b05d344164ebc52bb (patch) | |
tree | 8b76c40a9cf12bdf1ef53d6a217b3a582a05e341 /block/blk-flush.c | |
parent | 0b573692f19501dfe2aeaf37b272ec07f60c70b9 (diff) | |
download | lwn-c1075e548ce6e6b5c7b71f2b05d344164ebc52bb.tar.gz lwn-c1075e548ce6e6b5c7b71f2b05d344164ebc52bb.zip |
blk-mq: reflow blk_insert_flush
Use a switch statement to decide on the disposition of a flush request
instead of multiple if statements, out of which one does checks that are
more complex than required. Also warn on a malformed request early
on instead of doing a BUG_ON later.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20230519044050.107790-3-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-flush.c')
-rw-r--r-- | block/blk-flush.c | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c index ed37d272f787..d8144f1f6fb1 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -402,6 +402,9 @@ void blk_insert_flush(struct request *rq) struct blk_flush_queue *fq = blk_get_flush_queue(q, rq->mq_ctx); struct blk_mq_hw_ctx *hctx = rq->mq_hctx; + /* FLUSH/FUA request must never be merged */ + WARN_ON_ONCE(rq->bio != rq->biotail); + /* * @policy now records what operations need to be done. Adjust * REQ_PREFLUSH and FUA for the driver. @@ -417,39 +420,35 @@ void blk_insert_flush(struct request *rq) */ rq->cmd_flags |= REQ_SYNC; - /* - * An empty flush handed down from a stacking driver may - * translate into nothing if the underlying device does not - * advertise a write-back cache. In this case, simply - * complete the request. - */ - if (!policy) { + switch (policy) { + case 0: + /* + * An empty flush handed down from a stacking driver may + * translate into nothing if the underlying device does not + * advertise a write-back cache. In this case, simply + * complete the request. + */ blk_mq_end_request(rq, 0); return; - } - - BUG_ON(rq->bio != rq->biotail); /*assumes zero or single bio rq */ - - /* - * If there's data but flush is not necessary, the request can be - * processed directly without going through flush machinery. Queue - * for normal execution. - */ - if ((policy & REQ_FSEQ_DATA) && - !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { + case REQ_FSEQ_DATA: + /* + * If there's data, but no flush is necessary, the request can + * be processed directly without going through flush machinery. + * Queue for normal execution. + */ blk_mq_request_bypass_insert(rq, 0); blk_mq_run_hw_queue(hctx, false); return; + default: + /* + * Mark the request as part of a flush sequence and submit it + * for further processing to the flush state machine. + */ + blk_rq_init_flush(rq); + spin_lock_irq(&fq->mq_flush_lock); + blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0); + spin_unlock_irq(&fq->mq_flush_lock); } - - /* - * @rq should go through flush machinery. Mark it part of flush - * sequence and submit for further processing. - */ - blk_rq_init_flush(rq); - spin_lock_irq(&fq->mq_flush_lock); - blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0); - spin_unlock_irq(&fq->mq_flush_lock); } /** |