On 3/10/26 12:49, John Garry wrote:
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 <[email protected]>
---
  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 {

Please, don't. We should _not_ go into the business of doing TUR path checkers.
Path checkers turned out to be a major issue for multipathing, and
are mostly pointless for things like FC where you get reliable
path information via RSCNs.
Additionally I would advocate for scsi-multipath to be a _simple_
implementation, restricting to the most common scenarios. Namely
implicit ALUA only and reliable fabric notifications.
If you have anything else, fine, use dm-multipath.

Cheers,

Hannes
--
Dr. Hannes Reinecke                  Kernel Storage Architect
[email protected]                               +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

Reply via email to