Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5626860imu; Wed, 30 Jan 2019 00:27:03 -0800 (PST) X-Google-Smtp-Source: ALg8bN7qf8KhC7tXAZWRBm+YKHBIRaHt7bglBLTjSTmUj/AFuOXsWAy9whSIJgsCVPtWlRaMoG9D X-Received: by 2002:a62:5f07:: with SMTP id t7mr29406603pfb.108.1548836823542; Wed, 30 Jan 2019 00:27:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548836823; cv=none; d=google.com; s=arc-20160816; b=Cii9nhwK14EvfwPLiB1p9vQQzOGPq76W7wEywLLhS3rUpuudOsmy32zM14hR22//2G XgyvgN9FLVP8If/BwjItb9ux+ZcsBCe09/2ZQnXtr529bItItDBfB6dqio2wz90VUa5L 26XLx3FQvRd2L53uKY/octhkXKDmE14crbqTjnpL6Ogncy761MMllEKcv7dhkNHuFFnJ 3ZoRgi4ZVSs6qTC9jB3uZnGXXmL/vqtTSWf/BtrQZE21S7TvKYe/mWM98DYiIVw5DioO wjvUrjXjv5buA+4ogxUji/xf0fkqfX6d+wHIm1PeHNQajn+lI58stISMKQS8n84Y/Dr9 LsMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=4SJ08vbByDGEghofV2+//NIxp9tWhi8yWnv7uWvb0mg=; b=uGWxzUbgxHCyKJPYFjbXIpeVujZ5ivpSwIgVXiFbY0tepau5gqLja7oZuji2PeT40q Hi7VxRYunthxhVqzCg98Tbm3RtSElGwQkQ02hFd1RkF0PHwSkn4nAAP/kix6GtYv80NU wNvLeZrQSHPllIhYV897xGtsuRYrSEvUtBMDb+JXKLXPO9327X8Wak2xrlBLPEi1INrs FNzTVH/7KwGNysT+jSKRFpaHKJYMjCGAeyA8WCMJ0o3hPB+TFY1vqU5B/t9IbozXsa5d SjAQUwyq71EHvQVCeZsNnewJpYSdUjURbnNCuobwH0dXoav1PONq5r+kovBM7KWUUw5A SoQQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j132si916398pfc.84.2019.01.30.00.26.48; Wed, 30 Jan 2019 00:27:03 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730311AbfA3I0A (ORCPT + 99 others); Wed, 30 Jan 2019 03:26:00 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:2705 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730249AbfA3IZ6 (ORCPT ); Wed, 30 Jan 2019 03:25:58 -0500 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id F0827A44E62DB6304100; Wed, 30 Jan 2019 16:25:56 +0800 (CST) Received: from huawei.com (10.175.124.28) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.408.0; Wed, 30 Jan 2019 16:25:48 +0800 From: Jason Yan To: , CC: , , , , , , , , , , , , , Jason Yan , Ewan Milne , Tomas Henzl Subject: [PATCH v2 4/7] scsi: libsas: split the replacement of sas disks in two steps Date: Wed, 30 Jan 2019 16:24:09 +0800 Message-ID: <20190130082412.9357-5-yanaijie@huawei.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20190130082412.9357-1-yanaijie@huawei.com> References: <20190130082412.9357-1-yanaijie@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.124.28] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now if a new device replaced a old device, the sas address will change. We unregister the old device and discover the new device in one revalidation process. But after we deferred the sas_port_delete(), the sas port is not deleted when we registering the new port and device. The sas port cannot be added because the name of the new port is the same as the old. Fix this by doing the replacement in two steps. The first revalidation only delete the old device and trigger a new revalidation. The second revalidation discover the new device. To keep the event processing synchronised to the original event, we wrapped a loop and added a new parameter to see if we should revalidate again. Signed-off-by: Jason Yan CC: chenxiang CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_discover.c | 20 +++++++++++++++----- drivers/scsi/libsas/sas_expander.c | 20 ++++++++++++++------ include/scsi/libsas.h | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index ffc571a12916..c825c89fbddd 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -498,12 +498,10 @@ static void sas_discover_domain(struct work_struct *work) task_pid_nr(current), error); } -static void sas_revalidate_domain(struct work_struct *work) +static void sas_do_revalidate_domain(struct asd_sas_port *port, bool *retry) { - struct sas_discovery_event *ev = to_sas_discovery_event(work); - struct asd_sas_port *port = ev->port; - struct sas_ha_struct *ha = port->ha; struct domain_device *ddev = port->port_dev; + struct sas_ha_struct *ha = port->ha; /* prevent revalidation from finding sata links in recovery */ mutex_lock(&ha->disco_mutex); @@ -520,7 +518,7 @@ static void sas_revalidate_domain(struct work_struct *work) if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE || ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE)) - sas_ex_revalidate_domain(ddev); + sas_ex_revalidate_domain(ddev, retry); pr_debug("done REVALIDATING DOMAIN on port %d, pid:%d\n", port->id, task_pid_nr(current)); @@ -532,6 +530,18 @@ static void sas_revalidate_domain(struct work_struct *work) sas_probe_devices(port); } +static void sas_revalidate_domain(struct work_struct *work) +{ + struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct asd_sas_port *port = ev->port; + bool retry; + + do { + retry = false; + sas_do_revalidate_domain(port, &retry); + } while (retry); +} + /* ---------- Events ---------- */ static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 5cd720f93f96..cdbf8d8a28bf 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1994,7 +1994,8 @@ static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old) return false; } -static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) +static int sas_unregister(struct domain_device *dev, int phy_id, bool last, + bool *retry) { struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; @@ -2045,7 +2046,12 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) SAS_ADDR(phy->attached_sas_addr)); sas_unregister_devs_sas_addr(dev, phy_id, last); - return sas_discover_new(dev, phy_id); + /* force the next revalidation find this phy and bring it up */ + phy->phy_change_count = -1; + ex->ex_change_count = -1; + *retry = true; + + return 0; } /** @@ -2062,7 +2068,8 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) * first phy,for other phys in this port, we add it to the port to * forming the wide-port. */ -static void sas_rediscover(struct domain_device *dev, const int phy_id) +static void sas_rediscover(struct domain_device *dev, const int phy_id, + bool *retry) { struct expander_device *ex = &dev->ex_dev; struct ex_phy *changed_phy = &ex->ex_phy[phy_id]; @@ -2087,7 +2094,7 @@ static void sas_rediscover(struct domain_device *dev, const int phy_id) break; } } - res = sas_rediscover_dev(dev, phy_id, last); + res = sas_unregister(dev, phy_id, last, retry); } else res = sas_discover_new(dev, phy_id); @@ -2098,13 +2105,14 @@ static void sas_rediscover(struct domain_device *dev, const int phy_id) /** * sas_ex_revalidate_domain - revalidate the domain * @port_dev: port domain device. + * @retry: do we need to revalidate again * * NOTE: this process _must_ quit (return) as soon as any connection * errors are encountered. Connection recovery is done elsewhere. * Discover process only interrogates devices in order to discover the * domain. */ -void sas_ex_revalidate_domain(struct domain_device *port_dev) +void sas_ex_revalidate_domain(struct domain_device *port_dev, bool *retry) { int res; struct domain_device *dev = NULL; @@ -2119,7 +2127,7 @@ void sas_ex_revalidate_domain(struct domain_device *port_dev) res = sas_find_bcast_phy(dev, &phy_id, i, true); if (phy_id == -1) break; - sas_rediscover(dev, phy_id); + sas_rediscover(dev, phy_id, retry); i = phy_id + 1; } while (i < ex->num_phys); } diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index e557bcb0c266..deb75765e555 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -692,7 +692,7 @@ int sas_discover_root_expander(struct domain_device *); void sas_init_ex_attr(void); -void sas_ex_revalidate_domain(struct domain_device *); +void sas_ex_revalidate_domain(struct domain_device *port_dev, bool *retry); void sas_unregister_domain_devices(struct asd_sas_port *port, int gone); void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *); -- 2.14.4