diff --git a/patches/kernel/0016-block-fix-request.queuelist-usage-in-flush.patch b/patches/kernel/0016-block-fix-request.queuelist-usage-in-flush.patch new file mode 100644 index 0000000..e19842a --- /dev/null +++ b/patches/kernel/0016-block-fix-request.queuelist-usage-in-flush.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chengming Zhou +Date: Tue, 4 Jun 2024 14:47:45 +0800 +Subject: [PATCH] block: fix request.queuelist usage in flush + +Friedrich Weber reported a kernel crash problem and bisected to commit +81ada09cc25e ("blk-flush: reuse rq queuelist in flush state machine"). + +The root cause is that we use "list_move_tail(&rq->queuelist, pending)" +in the PREFLUSH/POSTFLUSH sequences. But rq->queuelist.next == xxx since +it's popped out from plug->cached_rq in __blk_mq_alloc_requests_batch(). +We don't initialize its queuelist just for this first request, although +the queuelist of all later popped requests will be initialized. + +Fix it by changing to use "list_add_tail(&rq->queuelist, pending)" so +rq->queuelist doesn't need to be initialized. It should be ok since rq +can't be on any list when PREFLUSH or POSTFLUSH, has no move actually. + +Please note the commit 81ada09cc25e ("blk-flush: reuse rq queuelist in +flush state machine") also has another requirement that no drivers would +touch rq->queuelist after blk_mq_end_request() since we will reuse it to +add rq to the post-flush pending list in POSTFLUSH. If this is not true, +we will have to revert that commit IMHO. + +Reported-by: Friedrich Weber +Closes: https://lore.kernel.org/lkml/14b89dfb-505c-49f7-aebb-01c54451db40@proxmox.com/ +Fixes: 81ada09cc25e ("blk-flush: reuse rq queuelist in flush state machine") +Cc: Christoph Hellwig +Cc: ming.lei@redhat.com +Cc: bvanassche@acm.org +Signed-off-by: Chengming Zhou +--- + block/blk-flush.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/blk-flush.c b/block/blk-flush.c +index 3f4d41952ef2..aa5e573dd010 100644 +--- a/block/blk-flush.c ++++ b/block/blk-flush.c +@@ -183,7 +183,7 @@ static void blk_flush_complete_seq(struct request *rq, + /* queue for flush */ + if (list_empty(pending)) + fq->flush_pending_since = jiffies; +- list_move_tail(&rq->queuelist, pending); ++ list_add_tail(&rq->queuelist, pending); + break; + + case REQ_FSEQ_DATA: