2024-06-04 13:34:31 +03:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Chengming Zhou <chengming.zhou@linux.dev>
|
2024-06-10 14:34:38 +03:00
|
|
|
Date: Sat, 8 Jun 2024 22:31:15 +0800
|
2024-06-04 13:34:31 +03:00
|
|
|
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.
|
|
|
|
|
2024-06-10 14:34:38 +03:00
|
|
|
This updated version adds "list_del_init(&rq->queuelist)" in flush rq
|
|
|
|
callback since the dm layer may submit request of a weird invalid format
|
|
|
|
(REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH), which causes double list_add
|
|
|
|
if without this "list_del_init(&rq->queuelist)". The weird invalid format
|
|
|
|
problem should be fixed in dm layer.
|
|
|
|
|
2024-06-04 13:34:31 +03:00
|
|
|
Reported-by: Friedrich Weber <f.weber@proxmox.com>
|
|
|
|
Closes: https://lore.kernel.org/lkml/14b89dfb-505c-49f7-aebb-01c54451db40@proxmox.com/
|
2024-06-10 14:34:38 +03:00
|
|
|
Closes: https://lore.kernel.org/lkml/c9d03ff7-27c5-4ebd-b3f6-5a90d96f35ba@proxmox.com/
|
2024-06-04 13:34:31 +03:00
|
|
|
Fixes: 81ada09cc25e ("blk-flush: reuse rq queuelist in flush state machine")
|
|
|
|
Cc: Christoph Hellwig <hch@lst.de>
|
|
|
|
Cc: ming.lei@redhat.com
|
|
|
|
Cc: bvanassche@acm.org
|
2024-06-10 14:34:38 +03:00
|
|
|
Tested-by: Friedrich Weber <f.weber@proxmox.com>
|
2024-06-04 13:34:31 +03:00
|
|
|
Signed-off-by: Chengming Zhou <chengming.zhou@linux.dev>
|
|
|
|
---
|
2024-06-10 14:34:38 +03:00
|
|
|
block/blk-flush.c | 3 ++-
|
|
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
2024-06-04 13:34:31 +03:00
|
|
|
|
|
|
|
diff --git a/block/blk-flush.c b/block/blk-flush.c
|
2024-06-10 14:34:38 +03:00
|
|
|
index 3f4d41952ef2..d72b57898b23 100644
|
2024-06-04 13:34:31 +03:00
|
|
|
--- 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:
|
2024-06-10 14:34:38 +03:00
|
|
|
@@ -261,6 +261,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq,
|
|
|
|
unsigned int seq = blk_flush_cur_seq(rq);
|
|
|
|
|
|
|
|
BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH);
|
|
|
|
+ list_del_init(&rq->queuelist);
|
|
|
|
blk_flush_complete_seq(rq, fq, seq, error);
|
|
|
|
}
|
|
|
|
|