When a request complete then send ipi to original cpu which issued request. If cpu offline during this process, send_ipi might fail. However, there is currently no code to handle this error case. This may cause in missing request complete. Therefore, if send_ipi fails due to cpu offline, the request complete has to be processed directly from the cpu where it is running. Signed-off-by: Manjong Lee <mj0123.lee@xxxxxxxxxxx> Signed-off-by: Changheun Lee <nanich.lee@xxxxxxxxxxx> Signed-off-by: Junho Kim <junho89.kim@xxxxxxxxxxx> --- block/blk-mq.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 3c1e6b6d991d..f2ce79708c5e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1064,17 +1064,22 @@ static inline bool blk_mq_complete_need_ipi(struct request *rq) return cpu_online(rq->mq_ctx->cpu); } -static void blk_mq_complete_send_ipi(struct request *rq) +static int blk_mq_complete_send_ipi(struct request *rq) { struct llist_head *list; unsigned int cpu; + int ret = 0; cpu = rq->mq_ctx->cpu; list = &per_cpu(blk_cpu_done, cpu); if (llist_add(&rq->ipi_list, list)) { INIT_CSD(&rq->csd, __blk_mq_complete_request_remote, rq); - smp_call_function_single_async(cpu, &rq->csd); + ret = smp_call_function_single_async(cpu, &rq->csd); + if (ret) + llist_del_all(list); } + + return ret; } static void blk_mq_raise_softirq(struct request *rq) @@ -1099,10 +1104,9 @@ bool blk_mq_complete_request_remote(struct request *rq) if (rq->cmd_flags & REQ_POLLED) return false; - if (blk_mq_complete_need_ipi(rq)) { - blk_mq_complete_send_ipi(rq); - return true; - } + if (blk_mq_complete_need_ipi(rq)) + if (!blk_mq_complete_send_ipi(rq)) + return true; if (rq->q->nr_hw_queues == 1) { blk_mq_raise_softirq(rq); -- 2.32.0