blk_mq_try_issue_list_directly try to send a list requests belong to the same hctx to driver. Normally, we will send flush along with last request in the list by set last parameter in blk_mq_request_issue_directly. Extra flush is needed for two cases: 1. We stop sending at middle of list and normal flush along with last request will not be sent. 2. Error happens at sending last request and normal flush may be lost. We will only break list walk if we get BLK_STS_RESOURCE or BLK_STS_DEV_RESOURCE which will be stored in ret. So for case 1, we can simply check ret and send a extra flush if ret is not BLK_STS_OK. For case 2, the error of last request in the list is also stored in ret, we can simply check ret and send a extra flush if ret is not BLK_STS_OK too. Then error count is not needed and error in middle of list will not trigger unnecessary extra flush anymore. Signed-off-by: Kemeng Shi <shikemeng@xxxxxxxxxxxxxxx> --- block/blk-mq.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 01f48a73eacd..f67acd78a9c2 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2803,17 +2803,15 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, struct list_head *list) { int queued = 0; - int errors = 0; + blk_status_t ret; while (!list_empty(list)) { - blk_status_t ret; struct request *rq = list_first_entry(list, struct request, queuelist); list_del_init(&rq->queuelist); ret = blk_mq_request_issue_directly(rq, list_empty(list)); if (ret != BLK_STS_OK) { - errors++; if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE) { blk_mq_request_bypass_insert(rq, false, @@ -2830,7 +2828,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, * the driver there was more coming, but that turned out to * be a lie. */ - if (errors && hctx->queue->mq_ops->commit_rqs && queued) + if (ret != BLK_STS_OK && hctx->queue->mq_ops->commit_rqs && queued) hctx->queue->mq_ops->commit_rqs(hctx); } -- 2.30.0