Linux-NVME Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] nvme-multipath: defer partition scanning
@ 2024-10-15 14:31 Keith Busch
  2024-10-15 15:17 ` Christoph Hellwig
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Keith Busch @ 2024-10-15 14:31 UTC (permalink / raw)
  To: hch, linux-nvme; +Cc: Keith Busch, Hannes Reinecke

From: Keith Busch <kbusch@kernel.org>

We need to suppress the partition scan from occuring within the controller's
scan_work context. If a path error occurs here, the submission will wait until
a path becomes available or all paths are torn down, but that action also
occurs within scan_work, so it would deadlock. Defer the partion scan a
different one that does not block scan_work.

Reported-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>

will be ignored, and an empty message aborts the commit.
---
 drivers/nvme/host/multipath.c | 39 +++++++++++++++++++++++++++++------
 drivers/nvme/host/nvme.h      |  1 +
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index bad1620fbbfc1..d371aa03f9851 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -579,6 +579,20 @@ static int nvme_add_ns_head_cdev(struct nvme_ns_head *head)
 	return ret;
 }
 
+static void nvme_partition_scan_work(struct work_struct *work)
+{
+	struct nvme_ns_head *head =
+		container_of(work, struct nvme_ns_head, partition_scan_work);
+
+	if (WARN_ON_ONCE(!test_and_clear_bit(GD_SUPPRESS_PART_SCAN,
+					     &head->disk->state)))
+		return;
+
+	mutex_lock(&head->disk->open_mutex);
+	bdev_disk_changed(head->disk, false);
+	mutex_unlock(&head->disk->open_mutex);
+}
+
 static void nvme_requeue_work(struct work_struct *work)
 {
 	struct nvme_ns_head *head =
@@ -605,6 +619,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
 	bio_list_init(&head->requeue_list);
 	spin_lock_init(&head->requeue_lock);
 	INIT_WORK(&head->requeue_work, nvme_requeue_work);
+	INIT_WORK(&head->partition_scan_work, nvme_partition_scan_work);
 
 	/*
 	 * Add a multipath node if the subsystems supports multiple controllers.
@@ -628,6 +643,16 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
 		return PTR_ERR(head->disk);
 	head->disk->fops = &nvme_ns_head_ops;
 	head->disk->private_data = head;
+
+	/*
+	 * We need to suppress the partition scan from occuring within the
+	 * controller's scan_work context. If a path error occurs here, the
+	 * submission will wait until a path becomes available or all paths are
+	 * torn down, but that action also occurs within scan_work, so it would
+	 * deadlock. Defer the partion scan a different one that does not block
+	 * scan_work.
+	 */
+	set_bit(GD_SUPPRESS_PART_SCAN, &head->disk->state);
 	sprintf(head->disk->disk_name, "nvme%dn%d",
 			ctrl->subsys->instance, head->instance);
 	return 0;
@@ -654,6 +679,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
 			return;
 		}
 		nvme_add_ns_head_cdev(head);
+		kblockd_schedule_work(&head->partition_scan_work);
 	}
 
 	mutex_lock(&head->lock);
@@ -973,14 +999,14 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
 		return;
 	if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) {
 		nvme_cdev_del(&head->cdev, &head->cdev_device);
+		/*
+		 * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
+		 * to allow multipath to fail all I/O.
+		 */
+		synchronize_srcu(&head->srcu);
+		kblockd_schedule_work(&head->requeue_work);
 		del_gendisk(head->disk);
 	}
-	/*
-	 * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
-	 * to allow multipath to fail all I/O.
-	 */
-	synchronize_srcu(&head->srcu);
-	kblockd_schedule_work(&head->requeue_work);
 }
 
 void nvme_mpath_remove_disk(struct nvme_ns_head *head)
@@ -990,6 +1016,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
 	/* make sure all pending bios are cleaned up */
 	kblockd_schedule_work(&head->requeue_work);
 	flush_work(&head->requeue_work);
+	flush_work(&head->partition_scan_work);
 	put_disk(head->disk);
 }
 
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 313a4f978a2cf..093cb423f536b 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -494,6 +494,7 @@ struct nvme_ns_head {
 	struct bio_list		requeue_list;
 	spinlock_t		requeue_lock;
 	struct work_struct	requeue_work;
+	struct work_struct	partition_scan_work;
 	struct mutex		lock;
 	unsigned long		flags;
 #define NVME_NSHEAD_DISK_LIVE	0
-- 
2.43.5



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] nvme-multipath: defer partition scanning
  2024-10-15 14:31 [PATCH] nvme-multipath: defer partition scanning Keith Busch
@ 2024-10-15 15:17 ` Christoph Hellwig
  2024-10-20 23:39 ` Sagi Grimberg
  2024-10-21 10:23 ` Hannes Reinecke
  2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2024-10-15 15:17 UTC (permalink / raw)
  To: Keith Busch; +Cc: hch, linux-nvme, Keith Busch, Hannes Reinecke

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] nvme-multipath: defer partition scanning
  2024-10-15 14:31 [PATCH] nvme-multipath: defer partition scanning Keith Busch
  2024-10-15 15:17 ` Christoph Hellwig
@ 2024-10-20 23:39 ` Sagi Grimberg
  2024-10-21 10:23 ` Hannes Reinecke
  2 siblings, 0 replies; 4+ messages in thread
From: Sagi Grimberg @ 2024-10-20 23:39 UTC (permalink / raw)
  To: Keith Busch, hch, linux-nvme; +Cc: Keith Busch, Hannes Reinecke

Reviewed-by: Sagi Grimberg <sagi@grimberg.me>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] nvme-multipath: defer partition scanning
  2024-10-15 14:31 [PATCH] nvme-multipath: defer partition scanning Keith Busch
  2024-10-15 15:17 ` Christoph Hellwig
  2024-10-20 23:39 ` Sagi Grimberg
@ 2024-10-21 10:23 ` Hannes Reinecke
  2 siblings, 0 replies; 4+ messages in thread
From: Hannes Reinecke @ 2024-10-21 10:23 UTC (permalink / raw)
  To: Keith Busch, hch, linux-nvme; +Cc: Keith Busch

On 10/15/24 16:31, Keith Busch wrote:
> From: Keith Busch <kbusch@kernel.org>
> 
> We need to suppress the partition scan from occuring within the controller's
> scan_work context. If a path error occurs here, the submission will wait until
> a path becomes available or all paths are torn down, but that action also
> occurs within scan_work, so it would deadlock. Defer the partion scan a
> different one that does not block scan_work.
> 
> Reported-by: Hannes Reinecke <hare@suse.de>
> Signed-off-by: Keith Busch <kbusch@kernel.org>
> 
> will be ignored, and an empty message aborts the commit.
> ---
>   drivers/nvme/host/multipath.c | 39 +++++++++++++++++++++++++++++------
>   drivers/nvme/host/nvme.h      |  1 +
>   2 files changed, 34 insertions(+), 6 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                  Kernel Storage Architect
hare@suse.de                                +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-10-21 10:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-15 14:31 [PATCH] nvme-multipath: defer partition scanning Keith Busch
2024-10-15 15:17 ` Christoph Hellwig
2024-10-20 23:39 ` Sagi Grimberg
2024-10-21 10:23 ` Hannes Reinecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox