lkml.org 
[lkml]   [2021]   [May]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v2] nvme-multipath: Reset bdev to ns head when failover
Date
When a request finally completes in end_io() after it has failed over,
the bdev pointer can be stale and thus the system can crash. Set the
bdev back to ns head, so the request is map to an active path when
resubmitted.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
---
v2:
- commit header fix s/bi_disk/bdev/
- new commit message (hopefully it's better English this time.)
- dropped bdget_disk, use >disk->part0 directly as
suggested by hch

The patch is against nvme-5.13.

[ 6552.155244] Call Trace:
[ 6552.155251] bio_endio+0x74/0x120
[ 6552.155260] nvme_ns_head_submit_bio+0x36f/0x3e0 [nvme_core]
[ 6552.155266] ? __switch_to_asm+0x34/0x70
[ 6552.155269] ? __switch_to_asm+0x40/0x70
[ 6552.155271] submit_bio_noacct+0x175/0x490
[ 6552.155274] ? __switch_to_asm+0x34/0x70
[ 6552.155277] ? __switch_to_asm+0x34/0x70
[ 6552.155284] ? nvme_requeue_work+0x5a/0x70 [nvme_core]
[ 6552.155290] nvme_requeue_work+0x5a/0x70 [nvme_core]
[ 6552.155296] process_one_work+0x1f4/0x3e0
[ 6552.155299] worker_thread+0x2d/0x3e0
[ 6552.155302] ? process_one_work+0x3e0/0x3e0
[ 6552.155305] kthread+0x10d/0x130
[ 6552.155307] ? kthread_park+0xa0/0xa0
[ 6552.155311] ret_from_fork+0x35/0x40


drivers/nvme/host/multipath.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 0d0de3433f37..0551796517e6 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -70,6 +70,7 @@ void nvme_failover_req(struct request *req)
struct nvme_ns *ns = req->q->queuedata;
u16 status = nvme_req(req)->status & 0x7ff;
unsigned long flags;
+ struct bio *bio;

nvme_mpath_clear_current_path(ns);

@@ -84,6 +85,8 @@ void nvme_failover_req(struct request *req)
}

spin_lock_irqsave(&ns->head->requeue_lock, flags);
+ for (bio = req->bio; bio; bio = bio->bi_next)
+ bio_set_dev(bio, ns->head->disk->part0);
blk_steal_bios(&ns->head->requeue_list, req);
spin_unlock_irqrestore(&ns->head->requeue_lock, flags);

--
2.29.2
\
 
 \ /
  Last update: 2021-05-03 19:39    [W:0.035 / U:0.584 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site