mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Xingui Yang <yangxingui@huawei.com>
To: <john.g.garry@oracle.com>, <yanaijie@huawei.com>,
	<jejb@linux.ibm.com>, <martin.petersen@oracle.com>
Cc: <linux-scsi@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<linuxarm@huawei.com>, <liyihang9@h-partners.com>,
	<yangxingui@huawei.com>, <liuyonglong@huawei.com>,
	<kangfenglong@huawei.com>
Subject: [PATCH v3 2/2] scsi: libsas: Add linkrate and sas_addr change detection in rediscover
Date: Fri, 15 May 2026 16:45:31 +0800	[thread overview]
Message-ID: <20260515084531.866259-3-yangxingui@huawei.com> (raw)
In-Reply-To: <20260515084531.866259-1-yangxingui@huawei.com>

In sas_rediscover_dev(), when detecting a "flutter" condition (same SAS
address and compatible device type), the code assumes the device remains
unchanged and only handles SATA pending state recovery. However, this
approach misses two important scenarios:

First, the flutter detection only compares SAS address and device type,
ignoring potential linkrate changes that may have already occurred.

Second, after sas_ex_phy_discover() re-queries the expander phy, both
linkrate and attached SAS address may be updated. The current code does
not validate these changes against the existing child device.

Add validation checks after sas_ex_phy_discover() to detect linkrate and
sas_addr changes. When changes are detected, mark the device as gone and
schedule rediscovery via libsas's async discovery pattern:
- Set phy_change_count and ex_change_count to -1 to force revalidation
- Unregister the device and schedule DISCE_REVALIDATE_DOMAIN event
- The old device is destroyed by sas_destruct_devices()
- New event triggers discovery via sas_discover_new() since
  attached_sas_addr is cleared

Suggested-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
---
 drivers/scsi/libsas/sas_expander.c | 32 ++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index f55ae9a979cd..720db4128727 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -2017,15 +2017,39 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
 		goto out_free_resp;
 	} else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
 		   dev_type_flutter(type, phy->attached_dev_type)) {
-		struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
+		struct domain_device *child_dev = sas_ex_to_dev(dev, phy_id);
+		bool need_rediscover = false;
 		char *action = "";
 
 		sas_ex_phy_discover(dev, phy_id);
 
-		if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING)
+		if (child_dev && dev_is_sata(child_dev) &&
+		    phy->attached_dev_type == SAS_SATA_PENDING) {
 			action = ", needs recovery";
-		pr_debug("ex %016llx phy%02d broadcast flutter%s\n",
-			 SAS_ADDR(dev->sas_addr), phy_id, action);
+		} else if (child_dev && phy->linkrate != child_dev->linkrate) {
+			pr_info("ex %016llx phy%02d linkrate changed from %d to %d\n",
+				SAS_ADDR(dev->sas_addr), phy_id,
+				child_dev->linkrate, phy->linkrate);
+			need_rediscover = true;
+		} else if (child_dev &&
+			   SAS_ADDR(child_dev->sas_addr) != SAS_ADDR(phy->attached_sas_addr)) {
+			pr_info("ex %016llx phy%02d sas_addr changed from %016llx to %016llx\n",
+				SAS_ADDR(dev->sas_addr), phy_id,
+				SAS_ADDR(child_dev->sas_addr),
+				SAS_ADDR(phy->attached_sas_addr));
+			need_rediscover = true;
+		}
+
+		if (need_rediscover) {
+			set_bit(SAS_DEV_GONE, &child_dev->state);
+			phy->phy_change_count = -1;
+			ex->ex_change_count = -1;
+			sas_unregister_devs_sas_addr(dev, phy_id, true);
+			sas_discover_event(dev->port, DISCE_REVALIDATE_DOMAIN);
+		} else {
+			pr_debug("ex %016llx phy%02d broadcast flutter%s\n",
+				 SAS_ADDR(dev->sas_addr), phy_id, action);
+		}
 		goto out_free_resp;
 	}
 
-- 
2.43.0


  parent reply	other threads:[~2026-05-15  8:46 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-15  8:45 [PATCH v3 0/2] libsas: rediscover improvements for linkrate/sas_addr changes Xingui Yang
2026-05-15  8:45 ` [PATCH v3 1/2] scsi: libsas: refactor sas_ex_to_ata() using new helper sas_ex_to_dev() Xingui Yang
2026-05-21  8:04   ` John Garry
2026-05-15  8:45 ` Xingui Yang [this message]
2026-05-21  8:13   ` [PATCH v3 2/2] scsi: libsas: Add linkrate and sas_addr change detection in rediscover John Garry
2026-05-21  9:04     ` yangxingui
2026-05-22  9:16       ` John Garry
2026-05-25  2:25         ` yangxingui
2026-05-27  9:42           ` John Garry
2026-05-28  2:40             ` yangxingui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260515084531.866259-3-yangxingui@huawei.com \
    --to=yangxingui@huawei.com \
    --cc=jejb@linux.ibm.com \
    --cc=john.g.garry@oracle.com \
    --cc=kangfenglong@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=liuyonglong@huawei.com \
    --cc=liyihang9@h-partners.com \
    --cc=martin.petersen@oracle.com \
    --cc=yanaijie@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®