From patchwork Wed Jan 18 20:28:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cathy Avery X-Patchwork-Id: 9524757 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D2E176020B for ; Wed, 18 Jan 2017 20:39:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C20722861D for ; Wed, 18 Jan 2017 20:39:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B6FE428637; Wed, 18 Jan 2017 20:39:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3E90B2861D for ; Wed, 18 Jan 2017 20:39:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752175AbdARUg6 (ORCPT ); Wed, 18 Jan 2017 15:36:58 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56624 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752078AbdARUg4 (ORCPT ); Wed, 18 Jan 2017 15:36:56 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3972C79DB8; Wed, 18 Jan 2017 20:29:01 +0000 (UTC) Received: from dhcp-17-98.bos.redhat.com (vpn-56-232.rdu2.redhat.com [10.10.56.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4564297D14; Wed, 18 Jan 2017 20:29:00 +0000 (UTC) From: Cathy Avery To: kys@microsoft.com, haiyangz@microsoft.com, jejb@linux.vnet.ibm.com, martin.petersen@oracle.com Cc: devel@linuxdriverproject.org, linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org Subject: [PATCH 1/2] scsi: scsi_transport_fc: Provide a lightweight option for Virtual FC Hosts. Date: Wed, 18 Jan 2017 15:28:57 -0500 Message-Id: <1484771338-8903-2-git-send-email-cavery@redhat.com> In-Reply-To: <1484771338-8903-1-git-send-email-cavery@redhat.com> References: <1484771338-8903-1-git-send-email-cavery@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 18 Jan 2017 20:29:01 +0000 (UTC) Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The patch provides a means to offer a lightweight option to the current FC transport class. The new option is selected by a driver when it indicates it wants the lightweight transport via fc_function_template. Signed-off-by: Cathy Avery --- drivers/scsi/scsi_transport_fc.c | 125 +++++++++++++++++++++++++++++++++++++-- include/scsi/scsi_transport_fc.h | 1 + 2 files changed, 122 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 03577bd..4adc669 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -50,6 +50,15 @@ static int fc_bsg_hostadd(struct Scsi_Host *, struct fc_host_attrs *); static int fc_bsg_rportadd(struct Scsi_Host *, struct fc_rport *); static void fc_bsg_remove(struct request_queue *); static void fc_bsg_goose_queue(struct fc_rport *); +static int fc_host_lw_setup(struct Scsi_Host *, struct fc_host_attrs *); +static int fc_host_hw_setup(struct Scsi_Host *, struct fc_host_attrs *); +static int fc_host_hw_remove(struct fc_host_attrs *); +static struct scsi_transport_template * + fc_attach_lw_transport(struct fc_function_template *); +static struct scsi_transport_template * + fc_attach_hw_transport(struct fc_function_template *); +static void fc_remove_lw_host(struct Scsi_Host *); +static void fc_remove_hw_host(struct Scsi_Host *, struct fc_host_attrs *); /* * Module Parameters @@ -352,6 +361,10 @@ struct fc_internal { #define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t) + +static void fc_release_lw_transport(struct fc_internal *); +static void fc_release_hw_transport(struct fc_internal *); + static int fc_target_setup(struct transport_container *tc, struct device *dev, struct device *cdev) { @@ -387,7 +400,26 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev, { struct Scsi_Host *shost = dev_to_shost(dev); struct fc_host_attrs *fc_host = shost_to_fc_host(shost); + struct fc_internal *i = to_fc_internal(shost->transportt); + + if (i->f->lightweight_transport) + return fc_host_lw_setup(shost, fc_host); + + return fc_host_hw_setup(shost, fc_host); +} + +static int fc_host_lw_setup(struct Scsi_Host *shost, + struct fc_host_attrs *fc_host) +{ + fc_host->node_name = -1; + fc_host->port_name = -1; + + return 0; +} +static int fc_host_hw_setup(struct Scsi_Host *shost, + struct fc_host_attrs *fc_host) +{ /* * Set default values easily detected by the midlayer as * failure cases. The scsi lldd is responsible for initializing @@ -468,7 +500,16 @@ static int fc_host_remove(struct transport_container *tc, struct device *dev, { struct Scsi_Host *shost = dev_to_shost(dev); struct fc_host_attrs *fc_host = shost_to_fc_host(shost); + struct fc_internal *i = to_fc_internal(shost->transportt); + + if (i->f->lightweight_transport) + return 0; + return fc_host_hw_remove(fc_host); +} + +static int fc_host_hw_remove(struct fc_host_attrs *fc_host) +{ fc_bsg_remove(fc_host->rqst_q); return 0; } @@ -2175,6 +2216,49 @@ static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result) struct scsi_transport_template * fc_attach_transport(struct fc_function_template *ft) { + if (ft->lightweight_transport) + return fc_attach_lw_transport(ft); + + return fc_attach_hw_transport(ft); +} +EXPORT_SYMBOL(fc_attach_transport); + + +struct scsi_transport_template * +fc_attach_lw_transport(struct fc_function_template *ft) +{ + int count; + struct fc_internal *i; + + i = kzalloc(sizeof(struct fc_internal), + GFP_KERNEL); + + if (unlikely(!i)) + return NULL; + + i->t.host_attrs.ac.attrs = &i->host_attrs[0]; + i->t.host_attrs.ac.class = &fc_host_class.class; + i->t.host_attrs.ac.match = fc_host_match; + i->t.host_size = sizeof(struct fc_host_attrs); + transport_container_register(&i->t.host_attrs); + + i->f = ft; + + count = 0; + SETUP_HOST_ATTRIBUTE_RD(node_name); + SETUP_HOST_ATTRIBUTE_RD(port_name); + + BUG_ON(count > FC_HOST_NUM_ATTRS); + + i->host_attrs[count] = NULL; + + return &i->t; +} + + +struct scsi_transport_template * +fc_attach_hw_transport(struct fc_function_template *ft) +{ int count; struct fc_internal *i = kzalloc(sizeof(struct fc_internal), GFP_KERNEL); @@ -2318,12 +2402,27 @@ fc_attach_transport(struct fc_function_template *ft) return &i->t; } -EXPORT_SYMBOL(fc_attach_transport); void fc_release_transport(struct scsi_transport_template *t) { struct fc_internal *i = to_fc_internal(t); + if (i->f->lightweight_transport) + fc_release_lw_transport(i); + else + fc_release_hw_transport(i); +} +EXPORT_SYMBOL(fc_release_transport); + +void fc_release_lw_transport(struct fc_internal *i) +{ + transport_container_unregister(&i->t.host_attrs); + + kfree(i); +} + +void fc_release_hw_transport(struct fc_internal *i) +{ transport_container_unregister(&i->t.target_attrs); transport_container_unregister(&i->t.host_attrs); transport_container_unregister(&i->rport_attr_cont); @@ -2331,7 +2430,6 @@ void fc_release_transport(struct scsi_transport_template *t) kfree(i); } -EXPORT_SYMBOL(fc_release_transport); /** * fc_queue_work - Queue work to the fc_host workqueue. @@ -2438,10 +2536,30 @@ fc_flush_devloss(struct Scsi_Host *shost) void fc_remove_host(struct Scsi_Host *shost) { + struct fc_host_attrs *fc_host = shost_to_fc_host(shost); + struct fc_internal *i = to_fc_internal(shost->transportt); + + if (i->f->lightweight_transport) + fc_remove_lw_host(shost); + + else + fc_remove_hw_host(shost, fc_host); +} +EXPORT_SYMBOL(fc_remove_host); + +void +fc_remove_lw_host(struct Scsi_Host *shost) +{ + /* flush all scan work items */ + scsi_flush_work(shost); +} + +void +fc_remove_hw_host(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) +{ struct fc_vport *vport = NULL, *next_vport = NULL; struct fc_rport *rport = NULL, *next_rport = NULL; struct workqueue_struct *work_q; - struct fc_host_attrs *fc_host = shost_to_fc_host(shost); unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); @@ -2484,7 +2602,6 @@ fc_remove_host(struct Scsi_Host *shost) destroy_workqueue(work_q); } } -EXPORT_SYMBOL(fc_remove_host); static void fc_terminate_rport_io(struct fc_rport *rport) { diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 924c8e6..b1c03cc 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -718,6 +718,7 @@ struct fc_function_template { unsigned long show_host_system_hostname:1; unsigned long disable_target_scan:1; + unsigned long lightweight_transport:1; };