On 10/14/21 1:32 AM, Christoph Hellwig wrote: >> +void blk_mq_end_request_batch(struct io_batch *iob) >> +{ >> + int tags[TAG_COMP_BATCH], nr_tags = 0, acct_tags = 0; >> + struct blk_mq_hw_ctx *last_hctx = NULL; >> + struct request *rq; >> + u64 now = 0; >> + >> + while ((rq = rq_list_pop(&iob->req_list)) != NULL) { >> + if (!now && blk_mq_need_time_stamp(rq)) >> + now = ktime_get_ns(); >> + blk_update_request(rq, rq->status, blk_rq_bytes(rq)); >> + __blk_mq_end_request_acct(rq, rq->status, now); >> + >> + if (rq->q->elevator) { >> + blk_mq_free_request(rq); >> + continue; >> + } > > So why do we even bother adding requests with an elevator to the batch > list? You still get the benefit of amortized time keeping, and it's more efficient to complete in batches rather than one-at-the-time. It's just not as good as the non-elevator path. >> + /* >> + * csd is used for remote completions, fifo_time at scheduler time. >> + * They are mutually exclusive. result is used at completion time >> + * like csd, but for batched IO. Batched IO does not use IPI >> + * completions. >> + */ >> union { >> struct __call_single_data csd; >> u64 fifo_time; >> + blk_status_t status; >> }; > > The ->status field isn't needed any more now that error completions > aren't batched. Killed. -- Jens Axboe