[PATCH 7/8] scsi: scsi-multipath: Issue a periodic TUR per path

John Garry john.g.garry at oracle.com
Tue Mar 10 04:49:24 PDT 2026


To allow the initiator know of any ALUA configuration changes, issue a
periodic TUR.

multipathd does something similar for dm-multipath in terms of issuing
a periodic read per path.

The purpose of the TUR is that the target can update UA info in the TUR
response and the INI can handle it, but currently we don't for SCSI
multipath.

Signed-off-by: John Garry <john.g.garry at oracle.com>
---
 drivers/scsi/scsi_multipath.c | 36 +++++++++++++++++++++++++++++++++++
 include/scsi/scsi_multipath.h |  1 +
 2 files changed, 37 insertions(+)

diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c
index 0c34b1151f5bf..2b916c7af4bd7 100644
--- a/drivers/scsi/scsi_multipath.c
+++ b/drivers/scsi/scsi_multipath.c
@@ -4,6 +4,7 @@
  *
  */
 
+#include <linux/kthread.h>
 #include <scsi/scsi_alua.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_driver.h>
@@ -124,6 +125,7 @@ static void scsi_mpath_head_release(struct device *dev)
 		container_of(dev, struct scsi_mpath_head, dev);
 	struct mpath_head *mpath_head = scsi_mpath_head->mpath_head;
 
+	WARN_ON_ONCE(kthread_stop(scsi_mpath_head->kua));
 	scsi_mpath_delete_head(scsi_mpath_head);
 	bioset_exit(&scsi_mpath_head->bio_pool);
 	ida_free(&scsi_multipath_dev_ida, scsi_mpath_head->index);
@@ -514,6 +516,29 @@ struct mpath_head_template smpdt_pr = {
 	.device_groups = mpath_device_groups,
 };
 
+static void scsi_mpath_cb_ua_thread(struct mpath_device *mpath_device)
+{
+	struct scsi_mpath_device *scsi_mpath_dev =
+			to_scsi_mpath_device(mpath_device);
+
+	if (alua_tur(scsi_mpath_dev->sdev))
+		sdev_printk(KERN_NOTICE, scsi_mpath_dev->sdev,
+			    "%s: No target port descriptors found\n",
+			    __func__);
+}
+
+static int scsi_mpath_ua_thread(void *data)
+{
+	struct scsi_mpath_head *scsi_mpath_head = data;
+
+	while (!kthread_should_stop()) {
+		mpath_call_for_all_devices(scsi_mpath_head->mpath_head,
+			scsi_mpath_cb_ua_thread);
+		msleep(5000);
+	}
+	return 0;
+}
+
 static struct scsi_mpath_head *scsi_mpath_alloc_head(void)
 {
 	struct scsi_mpath_head *scsi_mpath_head;
@@ -548,6 +573,17 @@ static struct scsi_mpath_head *scsi_mpath_alloc_head(void)
 		goto out_free_ida;
 	}
 
+	scsi_mpath_head->kua = kthread_create(scsi_mpath_ua_thread,
+			scsi_mpath_head, "scsi-multipath-kua-%d",
+			scsi_mpath_head->index);
+	if (IS_ERR(scsi_mpath_head->kua)) {
+		put_device(&scsi_mpath_head->dev);
+		goto out_free_ida;
+	}
+
+	set_user_nice(scsi_mpath_head->kua, 10);
+	wake_up_process(scsi_mpath_head->kua);
+
 	return scsi_mpath_head;
 
 out_free_ida:
diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h
index 7c7ee2fb7def7..d30f2c41e17de 100644
--- a/include/scsi/scsi_multipath.h
+++ b/include/scsi/scsi_multipath.h
@@ -30,6 +30,7 @@ struct scsi_mpath_head {
 	struct mpath_head	*mpath_head;
 	struct device		dev;
 	int			index;
+	struct task_struct	*kua;
 };
 
 struct scsi_mpath_device {
-- 
2.43.5




More information about the Linux-nvme mailing list