Skip to content

Commit 40d09b5

Browse files
Christoph Hellwigaxboe
authored andcommitted
blk-mq: add a new blk_mq_complete_request_remote API
This is a variant of blk_mq_complete_request_remote that only completes the request if it needs to be bounced to another CPU or a softirq. If the request can be completed locally the function returns false and lets the driver complete it without requring and indirect function call. Reviewed-by: Daniel Wagner <dwagner@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 9633952 commit 40d09b5

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

block/blk-mq.c

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -632,8 +632,11 @@ static int blk_softirq_cpu_dead(unsigned int cpu)
632632
return 0;
633633
}
634634

635-
static void __blk_mq_complete_request(struct request *rq)
635+
636+
static void __blk_mq_complete_request_remote(void *data)
636637
{
638+
struct request *rq = data;
639+
637640
/*
638641
* For most of single queue controllers, there is only one irq vector
639642
* for handling I/O completion, and the only irq's affinity is set
@@ -649,11 +652,6 @@ static void __blk_mq_complete_request(struct request *rq)
649652
rq->q->mq_ops->complete(rq);
650653
}
651654

652-
static void __blk_mq_complete_request_remote(void *data)
653-
{
654-
__blk_mq_complete_request(data);
655-
}
656-
657655
static inline bool blk_mq_complete_need_ipi(struct request *rq)
658656
{
659657
int cpu = raw_smp_processor_id();
@@ -672,34 +670,43 @@ static inline bool blk_mq_complete_need_ipi(struct request *rq)
672670
return cpu_online(rq->mq_ctx->cpu);
673671
}
674672

675-
/**
676-
* blk_mq_complete_request - end I/O on a request
677-
* @rq: the request being processed
678-
*
679-
* Description:
680-
* Complete a request by scheduling the ->complete_rq operation.
681-
**/
682-
void blk_mq_complete_request(struct request *rq)
673+
bool blk_mq_complete_request_remote(struct request *rq)
683674
{
684675
WRITE_ONCE(rq->state, MQ_RQ_COMPLETE);
685676

686677
/*
687678
* For a polled request, always complete locallly, it's pointless
688679
* to redirect the completion.
689680
*/
690-
if (rq->cmd_flags & REQ_HIPRI) {
691-
rq->q->mq_ops->complete(rq);
692-
return;
693-
}
681+
if (rq->cmd_flags & REQ_HIPRI)
682+
return false;
694683

695684
if (blk_mq_complete_need_ipi(rq)) {
696685
rq->csd.func = __blk_mq_complete_request_remote;
697686
rq->csd.info = rq;
698687
rq->csd.flags = 0;
699688
smp_call_function_single_async(rq->mq_ctx->cpu, &rq->csd);
700689
} else {
701-
__blk_mq_complete_request(rq);
690+
if (rq->q->nr_hw_queues > 1)
691+
return false;
692+
blk_mq_trigger_softirq(rq);
702693
}
694+
695+
return true;
696+
}
697+
EXPORT_SYMBOL_GPL(blk_mq_complete_request_remote);
698+
699+
/**
700+
* blk_mq_complete_request - end I/O on a request
701+
* @rq: the request being processed
702+
*
703+
* Description:
704+
* Complete a request by scheduling the ->complete_rq operation.
705+
**/
706+
void blk_mq_complete_request(struct request *rq)
707+
{
708+
if (!blk_mq_complete_request_remote(rq))
709+
rq->q->mq_ops->complete(rq);
703710
}
704711
EXPORT_SYMBOL(blk_mq_complete_request);
705712

include/linux/blk-mq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list);
504504
void blk_mq_kick_requeue_list(struct request_queue *q);
505505
void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs);
506506
void blk_mq_complete_request(struct request *rq);
507+
bool blk_mq_complete_request_remote(struct request *rq);
507508
bool blk_mq_bio_list_merge(struct request_queue *q, struct list_head *list,
508509
struct bio *bio, unsigned int nr_segs);
509510
bool blk_mq_queue_stopped(struct request_queue *q);

0 commit comments

Comments
 (0)