From patchwork Wed Jan 4 15:39:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cathy Avery X-Patchwork-Id: 9497041 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 AFFF3606B4 for ; Wed, 4 Jan 2017 15:39:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A0EF827FE4 for ; Wed, 4 Jan 2017 15:39:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92AF828068; Wed, 4 Jan 2017 15:39:51 +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=ham 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 EFF0827FE4 for ; Wed, 4 Jan 2017 15:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967165AbdADPjs (ORCPT ); Wed, 4 Jan 2017 10:39:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59818 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965062AbdADPjr (ORCPT ); Wed, 4 Jan 2017 10:39:47 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5B8748124F; Wed, 4 Jan 2017 15:39:48 +0000 (UTC) Received: from dhcp-17-98.bos.redhat.com (dhcp-17-80.bos.redhat.com [10.18.17.80]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v04FdlJj017656; Wed, 4 Jan 2017 10:39:47 -0500 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: [RFC PATCH] scsi: scsi_transport_fc: Create a lightweight option for Virtual FC Hosts. Date: Wed, 4 Jan 2017 10:39:46 -0500 Message-Id: <1483544386-6008-1-git-send-email-cavery@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 04 Jan 2017 15:39:48 +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 This patch represents an attempt to resurrect the conversation based on the submission of patch: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V K. Y. Srinivasan kys at microsoft.com Sat Mar 12 21:52:48 UTC 2016 http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2016-March/087116.html That patch attempted to address the problem of not being able to scan FC hosts on a Hyper-V guest via sysfs due to the fact that they did not contain the complete characteristic set associated with a normal FC host ( missing rports, vports, etc ). These new lightweight hosts as they were subsequently referred to are not consistent with the current FC transport model. The patch below provides a method to reconcile the issue by offering 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 in fc_function_template. I have included the changes for storvsc_drv.c in this patch as an example of a driver making use of the lightweight transport option. Signed-off-by: Cathy Avery --- drivers/scsi/scsi_transport_fc.c | 125 +++++++++++++++++++++++++++++++++++++-- drivers/scsi/storvsc_drv.c | 6 +- include/scsi/scsi_transport_fc.h | 1 + 3 files changed, 123 insertions(+), 9 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/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 888e16e..fc1d6ba 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1882,6 +1882,7 @@ static struct hv_driver storvsc_drv = { static struct fc_function_template fc_transport_functions = { .show_host_node_name = 1, .show_host_port_name = 1, + .lightweight_transport = 1, }; #endif @@ -1906,11 +1907,6 @@ static int __init storvsc_drv_init(void) fc_transport_template = fc_attach_transport(&fc_transport_functions); if (!fc_transport_template) return -ENODEV; - - /* - * Install Hyper-V specific timeout handler. - */ - fc_transport_template->eh_timed_out = storvsc_eh_timed_out; #endif ret = vmbus_driver_register(&storvsc_drv); 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; };