Requeue requests instead of sending these to the dispatch list if a CPU is unplugged. This gives the I/O scheduler the chance to preserve the order of zoned write requests. Cc: Christoph Hellwig <hch@xxxxxx> Cc: Damien Le Moal <dlemoal@xxxxxxxxxx> Cc: Ming Lei <ming.lei@xxxxxxxxxx> Cc: Mike Snitzer <snitzer@xxxxxxxxxx> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- block/blk-mq.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 632aee9af60f..bc52a57641e2 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3497,13 +3497,13 @@ static int blk_mq_hctx_notify_online(unsigned int cpu, struct hlist_node *node) } /* - * 'cpu' is going away. splice any existing rq_list entries from this - * software queue to the hw queue dispatch list, and ensure that it - * gets run. + * @cpu is going away. Requeue any existing rq_list entries from its + * software queue and run the hw queue associated with @cpu. */ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node) { struct blk_mq_hw_ctx *hctx; + struct request *rq, *next; struct blk_mq_ctx *ctx; LIST_HEAD(tmp); enum hctx_type type; @@ -3525,9 +3525,9 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node) if (list_empty(&tmp)) return 0; - spin_lock(&hctx->lock); - list_splice_tail_init(&tmp, &hctx->dispatch); - spin_unlock(&hctx->lock); + list_for_each_entry_safe(rq, next, &tmp, queuelist) + blk_mq_requeue_request(rq, false); + blk_mq_kick_requeue_list(hctx->queue); blk_mq_run_hw_queue(hctx, true); return 0;