From patchwork Mon Jul 10 07:06:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wangyijing X-Patchwork-Id: 107275 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp3038226qge; Mon, 10 Jul 2017 00:02:58 -0700 (PDT) X-Received: by 10.98.98.199 with SMTP id w190mr37906066pfb.44.1499670178610; Mon, 10 Jul 2017 00:02:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499670178; cv=none; d=google.com; s=arc-20160816; b=Vew+JfDNnPapVPhhOgapPGbKNLQs1NS3a0YLORSP4VlNXv0a/os3UV8853unE0HzWR 5mr9x5/E1KBKR2L0lU3pcZ0OmX2SjM14aN2Vfinlhi29zceravDy+GxHtaAyh8kYRqlb 3gDmVMoiI9BSRvlgX0TwHXuI4osE4pVRbwSwApvFRbN/fWpdsGtXnbmlqcCzMY3SGsPI 3lNgUxZNQOjhHFPeQZLaTNO7JvCg68k7JeO1OERGvXwacxtD0dvz6If7HrGPPiwHmeT1 vb22ZBPqjfDJv6YmL1aknSOM3sMF1i2RLmjtZjirZhfobYcGKaBqFbRuauLA2/k2sk8u zYjQ== 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:arc-authentication-results; bh=VUyI//NWXYOoJo1zJZYDAr6LNzBKpEB/SmVsVNVJH38=; b=EkV9Fk3lLAyzy8n8S1m8+2W8QeerSkWgWQ6PJDhwK7lwLV29SSnxg2Ologo3YyeQOW Ch+on9HQa70jhBo2Op5muylHWt3vePD/BuFMECCdawjyxEQ20BCx+EwDnR7DGUap3891 nMNRTvOeMXv+c4v5CitXchR18y10DeyrFxm5T+1RX3C6LiRDgUWigJKSr80zoNHGd6YE tEEBFhRjvgpt/3b9SKSQ08Ef8JaQhz64ayPJL1T9pYw4ZPcwaTO07F8V6EJjbbVx8qRW KDsP4bRrNOg9SdrJtjSRK0/7FdFYDPlFxLKm5knK8hpd5fTNum5P+6noMWRXE0LJPQJM dK2g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-scsi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-scsi-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 f5si7528255pgk.495.2017.07.10.00.02.58; Mon, 10 Jul 2017 00:02:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-scsi-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-scsi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-scsi-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753447AbdGJHCc (ORCPT + 1 other); Mon, 10 Jul 2017 03:02:32 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:9812 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751163AbdGJHCa (ORCPT ); Mon, 10 Jul 2017 03:02:30 -0400 Received: from 172.30.72.53 (EHLO dggeml406-hub.china.huawei.com) ([172.30.72.53]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AQU38390; Mon, 10 Jul 2017 15:02:16 +0800 (CST) Received: from 138.huawei.com (10.175.124.28) by dggeml406-hub.china.huawei.com (10.3.17.50) with Microsoft SMTP Server id 14.3.301.0; Mon, 10 Jul 2017 15:02:07 +0800 From: Yijing Wang To: , CC: , , , , , , , , , , , , , , , , , , , Yijing Wang , "Johannes Thumshirn" Subject: [PATCH v3 6/7] libsas: add wait-complete support to sync discovery event Date: Mon, 10 Jul 2017 15:06:08 +0800 Message-ID: <1499670369-44143-7-git-send-email-wangyijing@huawei.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1499670369-44143-1-git-send-email-wangyijing@huawei.com> References: <1499670369-44143-1-git-send-email-wangyijing@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.124.28] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A0B0202.59632679.014F, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: a792165b6a31d2bb78355ddd1d947fa1 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Introduce a sync flag to tag discovery event whether need to sync execute, per-event wait-complete ensure sync. Signed-off-by: Yijing Wang CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams --- drivers/scsi/libsas/sas_discover.c | 8 ++++++-- drivers/scsi/libsas/sas_expander.c | 12 +++++++++++- drivers/scsi/libsas/sas_internal.h | 27 +++++++++++++++++++++++++++ include/scsi/libsas.h | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) -- 2.5.0 diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index a25d648..d68f8dd 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -378,6 +378,7 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) list_del_init(&dev->disco_list_node); sas_rphy_free(dev->rphy); sas_unregister_common_dev(port, dev); + sas_disc_cancel_sync(&port->disc.disc_work[DISCE_DESTRUCT]); return; } @@ -541,6 +542,7 @@ static void sas_discover_common_fn(struct work_struct *work) struct asd_sas_port *port = ev->port; sas_event_fns[ev->type](work); + sas_disc_wakeup(ev); sas_port_put(port); } @@ -571,8 +573,10 @@ static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) else ret = scsi_queue_work(ha->core.shost, &sw->work); - if (ret != 1) + if (ret != 1) { sas_port_put(port); + sas_disc_cancel_sync(ev); + } } static void sas_chain_event(int event, unsigned long *pending, @@ -592,9 +596,9 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) { struct sas_discovery *disc; + disc = &port->disc; if (!port) return 0; - disc = &port->disc; BUG_ON(ev >= DISC_NUM_EVENTS); diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 570b2cb..9d26c28 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -822,14 +822,18 @@ static struct domain_device *sas_ex_discover_end_dev( list_add_tail(&child->disco_list_node, &parent->port->disco_list); + sas_disc_wait_init(child->port, DISCE_PROBE); res = sas_discover_sata(child); if (res) { + sas_disc_cancel_sync(&child->port->disc.disc_work[DISCE_PROBE]); SAS_DPRINTK("sas_discover_sata() for device %16llx at " "%016llx:0x%x returned 0x%x\n", SAS_ADDR(child->sas_addr), SAS_ADDR(parent->sas_addr), phy_id, res); goto out_list_del; } + sas_disc_wait_completion(child->port, DISCE_PROBE); + } else #endif if (phy->attached_tproto & SAS_PROTOCOL_SSP) { @@ -847,14 +851,17 @@ static struct domain_device *sas_ex_discover_end_dev( list_add_tail(&child->disco_list_node, &parent->port->disco_list); + sas_disc_wait_init(child->port, DISCE_PROBE); res = sas_discover_end_dev(child); if (res) { + sas_disc_cancel_sync(&child->port->disc.disc_work[DISCE_PROBE]); SAS_DPRINTK("sas_discover_end_dev() for device %16llx " "at %016llx:0x%x returned 0x%x\n", SAS_ADDR(child->sas_addr), SAS_ADDR(parent->sas_addr), phy_id, res); goto out_list_del; } + sas_disc_wait_completion(child->port, DISCE_PROBE); } else { SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", phy->attached_tproto, SAS_ADDR(parent->sas_addr), @@ -1890,8 +1897,11 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, if (child->dev_type == SAS_EDGE_EXPANDER_DEVICE || child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) sas_unregister_ex_tree(parent->port, child); - else + else { + sas_disc_wait_init(parent->port, DISCE_DESTRUCT); sas_unregister_dev(parent->port, child); + sas_disc_wait_completion(parent->port, DISCE_DESTRUCT); + } found = child; break; } diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 890b5d26..09a9b10 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -134,6 +134,33 @@ static inline void sas_port_get(struct asd_sas_port *port) kref_get(&port->ref); } +static inline void sas_disc_cancel_sync(struct sas_discovery_event *event) +{ + event->is_sync = false; +} + +static inline void sas_disc_wakeup(struct sas_discovery_event *event) +{ + if (event->is_sync) + complete(&event->completion); +} + +static inline void sas_disc_wait_init(struct asd_sas_port *port, + enum discover_event event) +{ + port->disc.disc_work[event].is_sync = true; + init_completion(&port->disc.disc_work[event].completion); +} + +static inline void sas_disc_wait_completion(struct asd_sas_port *port, + enum discover_event event) +{ + if (port->disc.disc_work[event].is_sync) { + wait_for_completion(&port->disc.disc_work[event].completion); + port->disc.disc_work[event].is_sync = false; + } +} + #ifdef CONFIG_SCSI_SAS_HOST_SMP extern int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req, struct request *rsp); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 4bcb9fe..21e9fb140 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -243,6 +243,8 @@ struct sas_discovery_event { struct sas_work work; struct asd_sas_port *port; enum discover_event type; + bool is_sync; + struct completion completion; }; static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work)