From: wangyijing <wangyijing@huawei.com>
To: Hannes Reinecke <hare@suse.de>,
jejb@linux.vnet.ibm.com, martin.petersen@oracle.com
Cc: chenqilin2@huawei.com, hare@suse.com, linux-scsi@vger.kernel.org,
linux-kernel@vger.kernel.org, chenxiang66@hisilicon.com,
huangdaode@hisilicon.com, wangkefeng.wang@huawei.com,
zhaohongjiang@huawei.com, dingtianhong@huawei.com,
guohanjun@huawei.com, yanaijie@huawei.com, hch@lst.de,
dan.j.williams@intel.com, emilne@redhat.com, thenzl@redhat.com,
wefu@redhat.com, charles.chenxin@huawei.com,
chenweilong@huawei.com, john.garry@huawei.com,
Johannes Thumshirn <jthumshirn@suse.de>
Subject: Re: [PATCH v3 4/7] libsas: add sas event wait-complete support
Date: Fri, 14 Jul 2017 15:46:18 +0800 [thread overview]
Message-ID: <596876CA.2080001@huawei.com> (raw)
In-Reply-To: <b2939814-ebbe-866a-b067-e94d7e814647@suse.de>
在 2017/7/14 14:51, Hannes Reinecke 写道:
> On 07/10/2017 09:06 AM, Yijing Wang wrote:
>> Introduce wait-complete for libsas sas event processing,
>> execute sas port create/destruct in sync.
>>
>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>> CC: John Garry <john.garry@huawei.com>
>> CC: Johannes Thumshirn <jthumshirn@suse.de>
>> CC: Ewan Milne <emilne@redhat.com>
>> CC: Christoph Hellwig <hch@lst.de>
>> CC: Tomas Henzl <thenzl@redhat.com>
>> CC: Dan Williams <dan.j.williams@intel.com>
>> ---
>> drivers/scsi/libsas/sas_discover.c | 41 ++++++++++++++++++++++++++++----------
>> drivers/scsi/libsas/sas_internal.h | 34 +++++++++++++++++++++++++++++++
>> drivers/scsi/libsas/sas_port.c | 4 ++++
>> include/scsi/libsas.h | 5 ++++-
>> 4 files changed, 72 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
>> index 60de662..5d4a3a8 100644
>> --- a/drivers/scsi/libsas/sas_discover.c
>> +++ b/drivers/scsi/libsas/sas_discover.c
>> @@ -525,16 +525,43 @@ static void sas_revalidate_domain(struct work_struct *work)
>> mutex_unlock(&ha->disco_mutex);
>> }
>>
>> +static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
>> + [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
>> + [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
>> + [DISCE_PROBE] = sas_probe_devices,
>> + [DISCE_SUSPEND] = sas_suspend_devices,
>> + [DISCE_RESUME] = sas_resume_devices,
>> + [DISCE_DESTRUCT] = sas_destruct_devices,
>> +};
>> +
>> +/* a simple wrapper for sas discover event funtions */
>> +static void sas_discover_common_fn(struct work_struct *work)
>> +{
>> + struct sas_discovery_event *ev = to_sas_discovery_event(work);
>> + struct asd_sas_port *port = ev->port;
>> +
>> + sas_event_fns[ev->type](work);
>> + sas_port_put(port);
>> +}
>> +
>> +
>> /* ---------- Events ---------- */
>>
>> static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw)
>> {
>> + int ret;
>> + struct sas_discovery_event *ev = to_sas_discovery_event(&sw->work);
>> + struct asd_sas_port *port = ev->port;
>> +
>> /* chained work is not subject to SA_HA_DRAINING or
>> * SAS_HA_REGISTERED, because it is either submitted in the
>> * workqueue, or known to be submitted from a context that is
>> * not racing against draining
>> */
>> - scsi_queue_work(ha->core.shost, &sw->work);
>> + sas_port_get(port);
>> + ret = scsi_queue_work(ha->core.shost, &sw->work);
>> + if (ret != 1)
>> + sas_port_put(port);
>> }
>>
>> static void sas_chain_event(int event, unsigned long *pending,
>> @@ -575,18 +602,10 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
>> {
>> int i;
>>
>> - static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
>> - [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
>> - [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
>> - [DISCE_PROBE] = sas_probe_devices,
>> - [DISCE_SUSPEND] = sas_suspend_devices,
>> - [DISCE_RESUME] = sas_resume_devices,
>> - [DISCE_DESTRUCT] = sas_destruct_devices,
>> - };
>> -
>> disc->pending = 0;
>> for (i = 0; i < DISC_NUM_EVENTS; i++) {
>> - INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
>> + INIT_SAS_WORK(&disc->disc_work[i].work, sas_discover_common_fn);
>> disc->disc_work[i].port = port;
>> + disc->disc_work[i].type = i;
>> }
>> }
>> diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
>> index f03ce64..890b5d26 100644
>> --- a/drivers/scsi/libsas/sas_internal.h
>> +++ b/drivers/scsi/libsas/sas_internal.h
>> @@ -100,6 +100,40 @@ void sas_free_device(struct kref *kref);
>> extern const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS];
>> extern const work_func_t sas_port_event_fns[PORT_NUM_EVENTS];
>>
>> +static void sas_complete_event(struct kref *kref)
>> +{
>> + struct asd_sas_port *port = container_of(kref, struct asd_sas_port, ref);
>> +
>> + complete_all(&port->completion);
>> +}
>> +
>> +static inline void sas_port_put(struct asd_sas_port *port)
>> +{
>> + if (port->is_sync)
>> + kref_put(&port->ref, sas_complete_event);
>> +}
>> +
>> +static inline void sas_port_wait_init(struct asd_sas_port *port)
>> +{
>> + init_completion(&port->completion);
>> + kref_init(&port->ref);
>> + port->is_sync = true;
>> +}
>> +
>> +static inline void sas_port_wait_completion(
>> + struct asd_sas_port *port)
>> +{
>> + sas_port_put(port);
>> + wait_for_completion(&port->completion);
>> + port->is_sync = false;
>> +}
>> +
>> +static inline void sas_port_get(struct asd_sas_port *port)
>> +{
>> + if (port && port->is_sync)
>> + kref_get(&port->ref);
>> +}
>> +
>> #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/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
>> index 9326628..d589adb 100644
>> --- a/drivers/scsi/libsas/sas_port.c
>> +++ b/drivers/scsi/libsas/sas_port.c
>> @@ -191,7 +191,9 @@ static void sas_form_port(struct asd_sas_phy *phy)
>> if (si->dft->lldd_port_formed)
>> si->dft->lldd_port_formed(phy);
>>
>> + sas_port_wait_init(port);
>> sas_discover_event(phy->port, DISCE_DISCOVER_DOMAIN);
>> + sas_port_wait_completion(port);
>> }
>>
>> /**
>> @@ -218,7 +220,9 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
>> dev->pathways--;
>>
>> if (port->num_phys == 1) {
>> + sas_port_wait_init(port);
>> sas_unregister_domain_devices(port, gone);
>> + sas_port_wait_completion(port);
>> sas_port_delete(port->port);
>> port->port = NULL;
>> } else {
>
> I would rather use the standard on-stack completion here;
> like this:
>
> DECLARE_COMPLETION_ONSTACK(complete);
> port->completion = &complete;
> sas_unregister_domain_devices(port, gone);
> wait_for_completion(&complete);
> sas_port_delete(port->port);
>
> which would simplify the above helpers to:
>
> static inline void sas_port_put(struct asd_sas_port *port)
> {
> if (port->completion)
> kref_put(&port->ref, sas_complete_event);
> }
>
> and you could do away with the 'is_sync' helper.
It looks better, thanks!
>
> Cheers,
>
> Hannes
>
WARNING: multiple messages have this Message-ID (diff)
From: wangyijing <wangyijing@huawei.com>
To: Hannes Reinecke <hare@suse.de>, <jejb@linux.vnet.ibm.com>,
<martin.petersen@oracle.com>
Cc: <chenqilin2@huawei.com>, <hare@suse.com>,
<linux-scsi@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<chenxiang66@hisilicon.com>, <huangdaode@hisilicon.com>,
<wangkefeng.wang@huawei.com>, <zhaohongjiang@huawei.com>,
<dingtianhong@huawei.com>, <guohanjun@huawei.com>,
<yanaijie@huawei.com>, <hch@lst.de>, <dan.j.williams@intel.com>,
<emilne@redhat.com>, <thenzl@redhat.com>, <wefu@redhat.com>,
<charles.chenxin@huawei.com>, <chenweilong@huawei.com>,
<john.garry@huawei.com>, Johannes Thumshirn <jthumshirn@suse.de>
Subject: Re: [PATCH v3 4/7] libsas: add sas event wait-complete support
Date: Fri, 14 Jul 2017 15:46:18 +0800 [thread overview]
Message-ID: <596876CA.2080001@huawei.com> (raw)
In-Reply-To: <b2939814-ebbe-866a-b067-e94d7e814647@suse.de>
在 2017/7/14 14:51, Hannes Reinecke 写道:
> On 07/10/2017 09:06 AM, Yijing Wang wrote:
>> Introduce wait-complete for libsas sas event processing,
>> execute sas port create/destruct in sync.
>>
>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>> CC: John Garry <john.garry@huawei.com>
>> CC: Johannes Thumshirn <jthumshirn@suse.de>
>> CC: Ewan Milne <emilne@redhat.com>
>> CC: Christoph Hellwig <hch@lst.de>
>> CC: Tomas Henzl <thenzl@redhat.com>
>> CC: Dan Williams <dan.j.williams@intel.com>
>> ---
>> drivers/scsi/libsas/sas_discover.c | 41 ++++++++++++++++++++++++++++----------
>> drivers/scsi/libsas/sas_internal.h | 34 +++++++++++++++++++++++++++++++
>> drivers/scsi/libsas/sas_port.c | 4 ++++
>> include/scsi/libsas.h | 5 ++++-
>> 4 files changed, 72 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
>> index 60de662..5d4a3a8 100644
>> --- a/drivers/scsi/libsas/sas_discover.c
>> +++ b/drivers/scsi/libsas/sas_discover.c
>> @@ -525,16 +525,43 @@ static void sas_revalidate_domain(struct work_struct *work)
>> mutex_unlock(&ha->disco_mutex);
>> }
>>
>> +static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
>> + [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
>> + [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
>> + [DISCE_PROBE] = sas_probe_devices,
>> + [DISCE_SUSPEND] = sas_suspend_devices,
>> + [DISCE_RESUME] = sas_resume_devices,
>> + [DISCE_DESTRUCT] = sas_destruct_devices,
>> +};
>> +
>> +/* a simple wrapper for sas discover event funtions */
>> +static void sas_discover_common_fn(struct work_struct *work)
>> +{
>> + struct sas_discovery_event *ev = to_sas_discovery_event(work);
>> + struct asd_sas_port *port = ev->port;
>> +
>> + sas_event_fns[ev->type](work);
>> + sas_port_put(port);
>> +}
>> +
>> +
>> /* ---------- Events ---------- */
>>
>> static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw)
>> {
>> + int ret;
>> + struct sas_discovery_event *ev = to_sas_discovery_event(&sw->work);
>> + struct asd_sas_port *port = ev->port;
>> +
>> /* chained work is not subject to SA_HA_DRAINING or
>> * SAS_HA_REGISTERED, because it is either submitted in the
>> * workqueue, or known to be submitted from a context that is
>> * not racing against draining
>> */
>> - scsi_queue_work(ha->core.shost, &sw->work);
>> + sas_port_get(port);
>> + ret = scsi_queue_work(ha->core.shost, &sw->work);
>> + if (ret != 1)
>> + sas_port_put(port);
>> }
>>
>> static void sas_chain_event(int event, unsigned long *pending,
>> @@ -575,18 +602,10 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
>> {
>> int i;
>>
>> - static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
>> - [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
>> - [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
>> - [DISCE_PROBE] = sas_probe_devices,
>> - [DISCE_SUSPEND] = sas_suspend_devices,
>> - [DISCE_RESUME] = sas_resume_devices,
>> - [DISCE_DESTRUCT] = sas_destruct_devices,
>> - };
>> -
>> disc->pending = 0;
>> for (i = 0; i < DISC_NUM_EVENTS; i++) {
>> - INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
>> + INIT_SAS_WORK(&disc->disc_work[i].work, sas_discover_common_fn);
>> disc->disc_work[i].port = port;
>> + disc->disc_work[i].type = i;
>> }
>> }
>> diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
>> index f03ce64..890b5d26 100644
>> --- a/drivers/scsi/libsas/sas_internal.h
>> +++ b/drivers/scsi/libsas/sas_internal.h
>> @@ -100,6 +100,40 @@ void sas_free_device(struct kref *kref);
>> extern const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS];
>> extern const work_func_t sas_port_event_fns[PORT_NUM_EVENTS];
>>
>> +static void sas_complete_event(struct kref *kref)
>> +{
>> + struct asd_sas_port *port = container_of(kref, struct asd_sas_port, ref);
>> +
>> + complete_all(&port->completion);
>> +}
>> +
>> +static inline void sas_port_put(struct asd_sas_port *port)
>> +{
>> + if (port->is_sync)
>> + kref_put(&port->ref, sas_complete_event);
>> +}
>> +
>> +static inline void sas_port_wait_init(struct asd_sas_port *port)
>> +{
>> + init_completion(&port->completion);
>> + kref_init(&port->ref);
>> + port->is_sync = true;
>> +}
>> +
>> +static inline void sas_port_wait_completion(
>> + struct asd_sas_port *port)
>> +{
>> + sas_port_put(port);
>> + wait_for_completion(&port->completion);
>> + port->is_sync = false;
>> +}
>> +
>> +static inline void sas_port_get(struct asd_sas_port *port)
>> +{
>> + if (port && port->is_sync)
>> + kref_get(&port->ref);
>> +}
>> +
>> #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/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
>> index 9326628..d589adb 100644
>> --- a/drivers/scsi/libsas/sas_port.c
>> +++ b/drivers/scsi/libsas/sas_port.c
>> @@ -191,7 +191,9 @@ static void sas_form_port(struct asd_sas_phy *phy)
>> if (si->dft->lldd_port_formed)
>> si->dft->lldd_port_formed(phy);
>>
>> + sas_port_wait_init(port);
>> sas_discover_event(phy->port, DISCE_DISCOVER_DOMAIN);
>> + sas_port_wait_completion(port);
>> }
>>
>> /**
>> @@ -218,7 +220,9 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
>> dev->pathways--;
>>
>> if (port->num_phys == 1) {
>> + sas_port_wait_init(port);
>> sas_unregister_domain_devices(port, gone);
>> + sas_port_wait_completion(port);
>> sas_port_delete(port->port);
>> port->port = NULL;
>> } else {
>
> I would rather use the standard on-stack completion here;
> like this:
>
> DECLARE_COMPLETION_ONSTACK(complete);
> port->completion = &complete;
> sas_unregister_domain_devices(port, gone);
> wait_for_completion(&complete);
> sas_port_delete(port->port);
>
> which would simplify the above helpers to:
>
> static inline void sas_port_put(struct asd_sas_port *port)
> {
> if (port->completion)
> kref_put(&port->ref, sas_complete_event);
> }
>
> and you could do away with the 'is_sync' helper.
It looks better, thanks!
>
> Cheers,
>
> Hannes
>
next prev parent reply other threads:[~2017-07-14 7:46 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-10 7:06 [PATCH v3 0/7] Enhance libsas hotplug feature Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-10 7:06 ` [PATCH v3 1/7] libsas: Use static sas event pool to appease sas event lost Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-11 15:37 ` John Garry
2017-07-11 15:37 ` John Garry
2017-07-12 2:06 ` wangyijing
2017-07-12 2:06 ` wangyijing
2017-07-12 8:17 ` John Garry
2017-07-12 8:17 ` John Garry
2017-07-12 8:47 ` wangyijing
2017-07-12 8:47 ` wangyijing
2017-07-12 10:13 ` John Garry
2017-07-12 10:13 ` John Garry
2017-07-13 2:13 ` wangyijing
2017-07-13 2:13 ` wangyijing
2017-07-14 6:40 ` Hannes Reinecke
2017-07-10 7:06 ` [PATCH v3 2/7] libsas: remove unused port_gone_completion Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-11 15:54 ` John Garry
2017-07-11 15:54 ` John Garry
2017-07-12 2:18 ` wangyijing
2017-07-12 2:18 ` wangyijing
2017-07-14 6:40 ` Hannes Reinecke
2017-07-10 7:06 ` [PATCH v3 3/7] libsas: Use new workqueue to run sas event Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-14 6:42 ` Hannes Reinecke
2017-07-10 7:06 ` [PATCH v3 4/7] libsas: add sas event wait-complete support Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-14 6:51 ` Hannes Reinecke
2017-07-14 7:46 ` wangyijing [this message]
2017-07-14 7:46 ` wangyijing
2017-07-14 8:42 ` John Garry
2017-07-14 8:42 ` John Garry
2017-07-10 7:06 ` [PATCH v3 5/7] libsas: add a new workqueue to run probe/destruct discovery event Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-12 16:50 ` John Garry
2017-07-12 16:50 ` John Garry
2017-07-13 2:36 ` wangyijing
2017-07-13 2:36 ` wangyijing
2017-07-14 6:52 ` Hannes Reinecke
2017-07-10 7:06 ` [PATCH v3 6/7] libsas: add wait-complete support to sync " Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-12 13:51 ` John Garry
2017-07-12 13:51 ` John Garry
2017-07-13 2:19 ` wangyijing
2017-07-13 2:19 ` wangyijing
2017-07-14 6:53 ` Hannes Reinecke
2017-07-10 7:06 ` [PATCH v3 7/7] libsas: release disco mutex during waiting in sas_ex_discover_end_dev Yijing Wang
2017-07-10 7:06 ` Yijing Wang
2017-07-13 16:10 ` John Garry
2017-07-13 16:10 ` John Garry
2017-07-14 1:44 ` wangyijing
2017-07-14 1:44 ` wangyijing
2017-07-14 8:26 ` John Garry
2017-07-14 8:26 ` John Garry
2017-07-14 6:55 ` Hannes Reinecke
2017-07-12 9:59 ` [PATCH v3 0/7] Enhance libsas hotplug feature John Garry
2017-07-12 9:59 ` John Garry
2017-07-12 11:56 ` Johannes Thumshirn
2017-07-13 1:27 ` wangyijing
2017-07-13 1:27 ` wangyijing
2017-07-13 1:37 ` wangyijing
2017-07-13 1:37 ` wangyijing
2017-07-13 8:08 ` John Garry
2017-07-13 8:08 ` John Garry
2017-07-13 8:38 ` wangyijing
2017-07-13 8:38 ` wangyijing
2017-07-14 8:19 ` wangyijing
2017-07-14 8:19 ` wangyijing
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=596876CA.2080001@huawei.com \
--to=wangyijing@huawei.com \
--cc=charles.chenxin@huawei.com \
--cc=chenqilin2@huawei.com \
--cc=chenweilong@huawei.com \
--cc=chenxiang66@hisilicon.com \
--cc=dan.j.williams@intel.com \
--cc=dingtianhong@huawei.com \
--cc=emilne@redhat.com \
--cc=guohanjun@huawei.com \
--cc=hare@suse.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=huangdaode@hisilicon.com \
--cc=jejb@linux.vnet.ibm.com \
--cc=john.garry@huawei.com \
--cc=jthumshirn@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=thenzl@redhat.com \
--cc=wangkefeng.wang@huawei.com \
--cc=wefu@redhat.com \
--cc=yanaijie@huawei.com \
--cc=zhaohongjiang@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.