[PATCH] scsi: vmw_pscsi: Rearrange code to avoid multiple calls to free_irq during unload
Currently pvscsi_remove calls free_irq more than once as pvscsi_release_resources and __pvscsi_shutdown both call pvscsi_shutdown_intr. This results in a 'Trying to free already-free IRQ' warning and stack trace. To solve the problem pvscsi_shutdown_intr has been moved out of pvscsi_release_resources. Signed-off-by: Cathy Avery Reviewed-by: Ewan D. Milne --- drivers/scsi/vmw_pvscsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 6e49102..0d6b2a8 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -1202,8 +1202,6 @@ static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter) static void pvscsi_release_resources(struct pvscsi_adapter *adapter) { - pvscsi_shutdown_intr(adapter); - if (adapter->workqueue) destroy_workqueue(adapter->workqueue); @@ -1534,6 +1532,7 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) out_reset_adapter: ll_adapter_reset(adapter); out_release_resources: + pvscsi_shutdown_intr(adapter); pvscsi_release_resources(adapter); scsi_host_put(host); out_disable_device: @@ -1542,6 +1541,7 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) return error; out_release_resources_and_disable: + pvscsi_shutdown_intr(adapter); pvscsi_release_resources(adapter); goto out_disable_device; } -- 2.5.5 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] scsi: storvsc: Allow only one remove lun work item to be issued per lun
When running multipath on a VM if all available paths go down the driver can schedule large amounts of storvsc_remove_lun work items to the same lun. In response to the failing paths typically storvsc responds by taking host->scan_mutex and issuing a TUR per lun. If there has been heavy IO to the failed device all the failed IOs are returned from the host. A remove lun work item is issued per failed IO. If the outstanding TURs have not been completed in a timely manner the scan_mutex is never released or released too late. Consequently the many remove lun work items are not completed as scsi_remove_device also tries to take host->scan_mutex. This results in dragging the VM down and sometimes completely. This patch only allows one remove lun to be issued to a particular lun while it is an instantiated member of the scsi stack. Changes since v1: Use single threaded workqueue to serialize work in storvsc_handle_error [Christoph Hellwig] Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 27 ++- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 5e7200f..6febcdb 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -486,6 +486,8 @@ struct hv_host_device { unsigned int port; unsigned char path; unsigned char target; + struct workqueue_struct *handle_error_wq; + char work_q_name[20]; }; struct storvsc_scan_work { @@ -922,6 +924,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, { struct storvsc_scan_work *wrk; void (*process_err_fn)(struct work_struct *work); + struct hv_host_device *host_dev = shost_priv(host); bool do_work = false; switch (SRB_STATUS(vm_srb->srb_status)) { @@ -988,7 +991,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, wrk->lun = vm_srb->lun; wrk->tgt_id = vm_srb->target_id; INIT_WORK(&wrk->work, process_err_fn); - schedule_work(&wrk->work); + queue_work(host_dev->handle_error_wq, &wrk->work); } @@ -1803,10 +1806,19 @@ static int storvsc_probe(struct hv_device *device, if (stor_device->num_sc != 0) host->nr_hw_queues = stor_device->num_sc + 1; + /* +* Set the error handler work queue. +*/ + snprintf(host_dev->work_q_name, sizeof(host_dev->work_q_name), +"storvsc_error_wq_%d", host->host_no); + host_dev->handle_error_wq = + create_singlethread_workqueue(host_dev->work_q_name); + if (!host_dev->handle_error_wq) + goto err_out2; /* Register the HBA and start the scsi bus scan */ ret = scsi_add_host(host, &device->device); if (ret != 0) - goto err_out2; + goto err_out3; if (!dev_is_ide) { scsi_scan_host(host); @@ -1815,7 +1827,7 @@ static int storvsc_probe(struct hv_device *device, device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); if (ret) - goto err_out3; + goto err_out4; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { @@ -1827,14 +1839,17 @@ static int storvsc_probe(struct hv_device *device, fc_host_port_name(host) = stor_device->port_name; stor_device->rport = fc_remote_port_add(host, 0, &ids); if (!stor_device->rport) - goto err_out3; + goto err_out4; } #endif return 0; -err_out3: +err_out4: scsi_remove_host(host); +err_out3: + destroy_workqueue(host_dev->handle_error_wq); + err_out2: /* * Once we have connected with the host, we would need to @@ -1858,6 +1873,7 @@ static int storvsc_remove(struct hv_device *dev) { struct storvsc_device *stor_device = hv_get_drvdata(dev); struct Scsi_Host *host = stor_device->host; + struct hv_host_device *host_dev = shost_priv(host); #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { @@ -1865,6 +1881,7 @@ static int storvsc_remove(struct hv_device *dev) fc_remove_host(host); } #endif + destroy_workqueue(host_dev->handle_error_wq); scsi_remove_host(host); storvsc_dev_remove(dev); scsi_host_put(host); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH V2] scsi: storvsc: Allow only one remove lun work item to be issued per lun
When running multipath on a VM if all available paths go down the driver can schedule large amounts of storvsc_remove_lun work items to the same lun. In response to the failing paths typically storvsc responds by taking host->scan_mutex and issuing a TUR per lun. If there has been heavy IO to the failed device all the failed IOs are returned from the host. A remove lun work item is issued per failed IO. If the outstanding TURs have not been completed in a timely manner the scan_mutex is never released or released too late. Consequently the many remove lun work items are not completed as scsi_remove_device also tries to take host->scan_mutex. This results in dragging the VM down and sometimes completely. This patch only allows one remove lun to be issued to a particular lun while it is an instantiated member of the scsi stack. Changes since v1: Use single threaded workqueue to serialize work in storvsc_handle_error [Christoph Hellwig] Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 27 ++- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 5e7200f..6febcdb 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -486,6 +486,8 @@ struct hv_host_device { unsigned int port; unsigned char path; unsigned char target; + struct workqueue_struct *handle_error_wq; + char work_q_name[20]; }; struct storvsc_scan_work { @@ -922,6 +924,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, { struct storvsc_scan_work *wrk; void (*process_err_fn)(struct work_struct *work); + struct hv_host_device *host_dev = shost_priv(host); bool do_work = false; switch (SRB_STATUS(vm_srb->srb_status)) { @@ -988,7 +991,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, wrk->lun = vm_srb->lun; wrk->tgt_id = vm_srb->target_id; INIT_WORK(&wrk->work, process_err_fn); - schedule_work(&wrk->work); + queue_work(host_dev->handle_error_wq, &wrk->work); } @@ -1803,10 +1806,19 @@ static int storvsc_probe(struct hv_device *device, if (stor_device->num_sc != 0) host->nr_hw_queues = stor_device->num_sc + 1; + /* +* Set the error handler work queue. +*/ + snprintf(host_dev->work_q_name, sizeof(host_dev->work_q_name), +"storvsc_error_wq_%d", host->host_no); + host_dev->handle_error_wq = + create_singlethread_workqueue(host_dev->work_q_name); + if (!host_dev->handle_error_wq) + goto err_out2; /* Register the HBA and start the scsi bus scan */ ret = scsi_add_host(host, &device->device); if (ret != 0) - goto err_out2; + goto err_out3; if (!dev_is_ide) { scsi_scan_host(host); @@ -1815,7 +1827,7 @@ static int storvsc_probe(struct hv_device *device, device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); if (ret) - goto err_out3; + goto err_out4; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { @@ -1827,14 +1839,17 @@ static int storvsc_probe(struct hv_device *device, fc_host_port_name(host) = stor_device->port_name; stor_device->rport = fc_remote_port_add(host, 0, &ids); if (!stor_device->rport) - goto err_out3; + goto err_out4; } #endif return 0; -err_out3: +err_out4: scsi_remove_host(host); +err_out3: + destroy_workqueue(host_dev->handle_error_wq); + err_out2: /* * Once we have connected with the host, we would need to @@ -1858,6 +1873,7 @@ static int storvsc_remove(struct hv_device *dev) { struct storvsc_device *stor_device = hv_get_drvdata(dev); struct Scsi_Host *host = stor_device->host; + struct hv_host_device *host_dev = shost_priv(host); #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { @@ -1865,6 +1881,7 @@ static int storvsc_remove(struct hv_device *dev) fc_remove_host(host); } #endif + destroy_workqueue(host_dev->handle_error_wq); scsi_remove_host(host); storvsc_dev_remove(dev); scsi_host_put(host); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH V2] scsi: storvsc: Allow only one remove lun work item to be issued per lun
On 10/31/2017 08:24 AM, Martin K. Petersen wrote: If you use alloc_ordered_workqueue directly instead of create_singlethread_workqueue you can pass a format string and don't need the separate allocation. But I'm not sure if Tejun is fine with using __WQ_LEGACY directly.. The only thing that flag does is exempting the workqueue from possible flush deadlock check as we don't know whether WQ_MEM_RECLAIM on a legacy workqueue is intentional. There's no reason to add it when converting to alloc_ordered_workqueue(). Just decide whether it needs forward progress guarantee and use WQ_MEM_RECLAIM if so. Cathy? Sorry for the delay. Long was working on a similar problem and we needed to add a couple of extra patches. I was thinking of sending all three in series but I can send the V3 of this now and follow up with the additional patches. Does that make sense? ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH V3] scsi: storvsc: Allow only one remove lun work item to be issued per lun
When running multipath on a VM if all available paths go down the driver can schedule large amounts of storvsc_remove_lun work items to the same lun. In response to the failing paths typically storvsc responds by taking host->scan_mutex and issuing a TUR per lun. If there has been heavy IO to the failed device all the failed IOs are returned from the host. A remove lun work item is issued per failed IO. If the outstanding TURs have not been completed in a timely manner the scan_mutex is never released or released too late. Consequently the many remove lun work items are not completed as scsi_remove_device also tries to take host->scan_mutex. This results in dragging the VM down and sometimes completely. This patch only allows one remove lun to be issued to a particular lun while it is an instantiated member of the scsi stack. Changes since v1: Use single threaded workqueue to serialize work in storvsc_handle_error [Christoph Hellwig] Changes since v2: Replaced create_singlethread_workqueue with alloc_ordered_workqueue [Christoph Hellwig] Added reviewed by's. Signed-off-by: Cathy Avery Reviewed-by: Christoph Hellwig Reviewed-by: Long Li --- drivers/scsi/storvsc_drv.c | 26 +- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 5e7200f..7e3cd12 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -486,6 +486,7 @@ struct hv_host_device { unsigned int port; unsigned char path; unsigned char target; + struct workqueue_struct *handle_error_wq; }; struct storvsc_scan_work { @@ -922,6 +923,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, { struct storvsc_scan_work *wrk; void (*process_err_fn)(struct work_struct *work); + struct hv_host_device *host_dev = shost_priv(host); bool do_work = false; switch (SRB_STATUS(vm_srb->srb_status)) { @@ -988,7 +990,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, wrk->lun = vm_srb->lun; wrk->tgt_id = vm_srb->target_id; INIT_WORK(&wrk->work, process_err_fn); - schedule_work(&wrk->work); + queue_work(host_dev->handle_error_wq, &wrk->work); } @@ -1803,10 +1805,19 @@ static int storvsc_probe(struct hv_device *device, if (stor_device->num_sc != 0) host->nr_hw_queues = stor_device->num_sc + 1; + /* +* Set the error handler work queue. +*/ + host_dev->handle_error_wq = + alloc_ordered_workqueue("storvsc_error_wq_%d", + WQ_MEM_RECLAIM, + host->host_no); + if (!host_dev->handle_error_wq) + goto err_out2; /* Register the HBA and start the scsi bus scan */ ret = scsi_add_host(host, &device->device); if (ret != 0) - goto err_out2; + goto err_out3; if (!dev_is_ide) { scsi_scan_host(host); @@ -1815,7 +1826,7 @@ static int storvsc_probe(struct hv_device *device, device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); if (ret) - goto err_out3; + goto err_out4; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { @@ -1827,14 +1838,17 @@ static int storvsc_probe(struct hv_device *device, fc_host_port_name(host) = stor_device->port_name; stor_device->rport = fc_remote_port_add(host, 0, &ids); if (!stor_device->rport) - goto err_out3; + goto err_out4; } #endif return 0; -err_out3: +err_out4: scsi_remove_host(host); +err_out3: + destroy_workqueue(host_dev->handle_error_wq); + err_out2: /* * Once we have connected with the host, we would need to @@ -1858,6 +1872,7 @@ static int storvsc_remove(struct hv_device *dev) { struct storvsc_device *stor_device = hv_get_drvdata(dev); struct Scsi_Host *host = stor_device->host; + struct hv_host_device *host_dev = shost_priv(host); #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { @@ -1865,6 +1880,7 @@ static int storvsc_remove(struct hv_device *dev) fc_remove_host(host); } #endif + destroy_workqueue(host_dev->handle_error_wq); scsi_remove_host(host); storvsc_dev_remove(dev); scsi_host_put(host); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] storvsc: Avoid excessive host scan on controller change
On 10/31/2017 05:58 PM, Long Li wrote: From: Long Li When there are multiple disks attached to the same SCSI controller, the host may send several VSTOR_OPERATION_REMOVE_DEVICE or VSTOR_OPERATION_ENUMERATE_BUS messages in a row, to indicate there is a change on the SCSI controller. In response, storvsc rescans the SCSI host. There is no need to do multiple scans on the same host. Fix the code to do only one scan. Signed-off-by: Long Li --- drivers/scsi/storvsc_drv.c | 26 +++--- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 6febcdb..b602f52 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -488,6 +488,8 @@ struct hv_host_device { unsigned char target; struct workqueue_struct *handle_error_wq; char work_q_name[20]; + struct work_struct host_scan_work; + struct Scsi_Host *host; }; struct storvsc_scan_work { @@ -516,13 +518,12 @@ static void storvsc_device_scan(struct work_struct *work) static void storvsc_host_scan(struct work_struct *work) { - struct storvsc_scan_work *wrk; struct Scsi_Host *host; struct scsi_device *sdev; + struct hv_host_device *host_device = + container_of(work, struct hv_host_device, host_scan_work); - wrk = container_of(work, struct storvsc_scan_work, work); - host = wrk->host; - + host = host_device->host; /* * Before scanning the host, first check to see if any of the * currrently known devices have been hot removed. We issue a @@ -542,8 +543,6 @@ static void storvsc_host_scan(struct work_struct *work) * Now scan the host to discover LUNs that may have been added. */ scsi_scan_host(host); - - kfree(wrk); } static void storvsc_remove_lun(struct work_struct *work) @@ -1119,8 +1118,7 @@ static void storvsc_on_receive(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { - struct storvsc_scan_work *work; - + struct hv_host_device *host_dev; switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: storvsc_on_io_completion(stor_device, vstor_packet, request); @@ -1128,13 +1126,9 @@ static void storvsc_on_receive(struct storvsc_device *stor_device, case VSTOR_OPERATION_REMOVE_DEVICE: case VSTOR_OPERATION_ENUMERATE_BUS: - work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, storvsc_host_scan); - work->host = stor_device->host; - schedule_work(&work->work); + host_dev = shost_priv(stor_device->host); + queue_work( + host_dev->handle_error_wq, &host_dev->host_scan_work); break; case VSTOR_OPERATION_FCHBA_DATA: @@ -1747,6 +1741,7 @@ static int storvsc_probe(struct hv_device *device, host_dev->port = host->host_no; host_dev->dev = device; + host_dev->host = host; stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); @@ -1815,6 +1810,7 @@ static int storvsc_probe(struct hv_device *device, create_singlethread_workqueue(host_dev->work_q_name); if (!host_dev->handle_error_wq) goto err_out2; + INIT_WORK(&host_dev->host_scan_work, storvsc_host_scan); /* Register the HBA and start the scsi bus scan */ ret = scsi_add_host(host, &device->device); if (ret != 0) I've tested this patch with both a multipath failover while running fio and taking hyperV snap shots while luns are being hot added and removed. Tested-by: Cathy Avery ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] scsi: storvsc: Add support for FC rport.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the fact that the virtualized FC device does not expose rports. At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot of the VM. This patch stubs in an rport per fc_host in storvsc so that the requirement of a defined rport is now met within the fc_transport and echo "- - -" > /sys/class/scsi_host/hostX/scan now works. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 585e54f..6d7b932 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -478,6 +478,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1823,8 +1826,16 @@ static int storvsc_probe(struct hv_device *device, } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids; + + ids.node_name = 0; + ids.port_name = 0; + ids.port_id = 0; + ids.roles |= FC_PORT_ROLE_FCP_TARGET; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); } #endif return 0; @@ -1854,8 +1865,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] scsi: storvsc: Add support for FC rport.
Hi, I haven't received any feedback yet. Should I resend? Thanks, Cathy On 02/28/2017 01:45 PM, Cathy Avery wrote: Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the fact that the virtualized FC device does not expose rports. At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot of the VM. This patch stubs in an rport per fc_host in storvsc so that the requirement of a defined rport is now met within the fc_transport and echo "- - -" > /sys/class/scsi_host/hostX/scan now works. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 585e54f..6d7b932 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -478,6 +478,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1823,8 +1826,16 @@ static int storvsc_probe(struct hv_device *device, } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids; + + ids.node_name = 0; + ids.port_name = 0; + ids.port_id = 0; + ids.roles |= FC_PORT_ROLE_FCP_TARGET; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); } #endif return 0; @@ -1854,8 +1865,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] scsi: storvsc: Add support for FC rport.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the fact that the virtualized FC device does not expose rports. At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot of the VM. This patch stubs in an rport per fc_host in storvsc so that the requirement of a defined rport is now met within the fc_transport and echo "- - -" > /sys/class/scsi_host/hostX/scan now works. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 638e5f4..c6c0316 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -478,6 +478,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1823,8 +1826,16 @@ static int storvsc_probe(struct hv_device *device, } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids; + + ids.node_name = 0; + ids.port_name = 0; + ids.port_id = 0; + ids.roles |= FC_PORT_ROLE_FCP_TARGET; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); } #endif return 0; @@ -1854,8 +1865,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] scsi: storvsc: Add support for FC rport.
Good catch. Thanks! On 03/14/2017 12:42 PM, Stephen Hemminger wrote: On Tue, 14 Mar 2017 12:01:03 -0400 Cathy Avery wrote: #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids; + + ids.node_name = 0; + ids.port_name = 0; + ids.port_id = 0; + ids.roles |= FC_PORT_ROLE_FCP_TARGET; Since the variable ids is on the stack, it is uninitialized data. Doing a OR with uninitialized data is not correct. Better off to use C99 style iniatializer and skip the zero fields. struct fc_rport_identifiers ids = { .roles = FC_PORT_ROLE_FCP_TARGET, }; ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2] scsi: storvsc: Add support for FC rport.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the fact that the virtualized FC device does not expose rports. At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot of the VM. This patch stubs in an rport per fc_host in storvsc so that the requirement of a defined rport is now met within the fc_transport and echo "- - -" > /sys/class/scsi_host/hostX/scan now works. Signed-off-by: Cathy Avery --- Changes since v1: - Fix fc_rport_identifiers init [Stephen Hemminger] - Better error checking --- drivers/scsi/storvsc_drv.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 638e5f4..37646d1 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -478,6 +478,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1816,19 +1819,27 @@ static int storvsc_probe(struct hv_device *device, target = (device->dev_instance.b[5] << 8 | device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); - if (ret) { - scsi_remove_host(host); - goto err_out2; - } + if (ret) + goto err_out3; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids = { + .roles = FC_PORT_ROLE_FCP_TARGET, + }; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); + if (!stor_device->rport) + goto err_out3; } #endif return 0; +err_out3: + scsi_remove_host(host); + err_out2: /* * Once we have connected with the host, we would need to @@ -1854,8 +1865,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [REGRESSION][Stable][v3.12.y][v4.4.y][v4.9.y][v4.10.y][v4.11-rc1] scsi: storvsc: properly set residual data length on errors
Hi, So which commit is moving forward and which one is not? f1c635b439a5c01776fe3a25b1e2dc546ea82e6f or 40630f462824ee24bc00d692865c86c3828094e0? We have backported 40630f462824ee24bc00d692865c86c3828094e0 and I am unclear if this is a regression and must be removed or it is a regression but is fixed by f1c635b439a5c01776fe3a25b1e2dc546ea82e6f and can remain. Thanks, Cathy On 03/28/2017 12:14 PM, Stephen Hemminger wrote: I decided not to send it to stable since problem was only observed on 4.11 but it is probably endemic to all GEN2 VM's -Original Message- From: Joseph Salisbury [mailto:joseph.salisb...@canonical.com] Sent: Tuesday, March 28, 2017 7:29 AM To: Stephen Hemminger ; Long Li Cc: KY Srinivasan ; Martin K. Petersen ; Haiyang Zhang ; j...@linux.vnet.ibm.com; de...@linuxdriverproject.org; linux-scsi ; LKML ; sta...@vger.kernel.org; Greg KH Subject: Re: [REGRESSION][Stable][v3.12.y][v4.4.y][v4.9.y][v4.10.y][v4.11-rc1] scsi: storvsc: properly set residual data length on errors On 03/27/2017 06:14 PM, Stephen Hemminger wrote: Are you sure the real problem is not the one fixed by this commit? commit f1c635b439a5c01776fe3a25b1e2dc546ea82e6f Author: Stephen Hemminger Date: Tue Mar 7 09:15:53 2017 -0800 scsi: storvsc: Workaround for virtual DVD SCSI version Hyper-V host emulation of SCSI for virtual DVD device reports SCSI version 0 (UNKNOWN) but is still capable of supporting REPORTLUN. Without this patch, a GEN2 Linux guest on Hyper-V will not boot 4.11 successfully with virtual DVD ROM device. What happens is that the SCSI scan process falls back to doing sequential probing by INQUIRY. But the storvsc driver has a previous workaround that masks/blocks all errors reports from INQUIRY (or MODE_SENSE) commands. This workaround causes the scan to then populate a full set of bogus LUN's on the target and then sends kernel spinning off into a death spiral doing block reads on the non-existent LUNs. By setting the correct blacklist flags, the target with the DVD device is scanned with REPORTLUN and that works correctly. Patch needs to go in current 4.11, it is safe but not necessary in older kernels. Signed-off-by: Stephen Hemminger Reviewed-by: K. Y. Srinivasan Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen -Original Message- From: Joseph Salisbury [mailto:joseph.salisb...@canonical.com] Sent: Monday, March 27, 2017 1:22 PM To: Long Li Cc: KY Srinivasan ; Martin K. Petersen ; Haiyang Zhang ; Stephen Hemminger ; j...@linux.vnet.ibm.com; de...@linuxdriverproject.org; linux-scsi ; LKML ; sta...@vger.kernel.org; Greg KH Subject: [REGRESSION][Stable][v3.12.y][v4.4.y][v4.9.y][v4.10.y][v4.11-rc1] scsi: storvsc: properly set residual data length on errors Hi Long Li, A kernel bug report was opened against Ubuntu [0]. After a kernel bisect, it was found that reverting the following commit resolved this bug: commit 40630f462824ee24bc00d692865c86c3828094e0 Author: Long Li Date: Wed Dec 14 18:46:03 2016 -0800 scsi: storvsc: properly set residual data length on errors The regression was introduced in mainline as of v4.11-rc1. It was also cc'd to stable and has landed in v3.12.y, v4.4.y, v4.9.y and v4.10.y. This regression seems pretty severe since it's preventing virtual machines from booting. It's affecting a couple of users so far. I was hoping to get your feedback, since you are the patch author. Do you think gathering any additional data will help diagnose this issue, or would it be best to submit a revert request? Thanks, Joe [0] http://pad.lv/1674635 Hi Stephen, Thanks again for pointing out commit f1c635b439a5c01776fe3a25b1e2dc546ea82e6f. It does indeed fix the bug. I noticed the commit was not cc'd to stable. Would it be possible to do that? Thanks, Joe ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2] scsi: storvsc: Add support for FC rport.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the fact that the virtualized FC device does not expose rports. At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot of the VM. This patch stubs in an rport per fc_host in storvsc so that the requirement of a defined rport is now met within the fc_transport and echo "- - -" > /sys/class/scsi_host/hostX/scan now works. Signed-off-by: Cathy Avery --- Changes since v1: - Fix fc_rport_identifiers init [Stephen Hemminger] - Better error checking --- drivers/scsi/storvsc_drv.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 638e5f4..37646d1 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -478,6 +478,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1816,19 +1819,27 @@ static int storvsc_probe(struct hv_device *device, target = (device->dev_instance.b[5] << 8 | device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); - if (ret) { - scsi_remove_host(host); - goto err_out2; - } + if (ret) + goto err_out3; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids = { + .roles = FC_PORT_ROLE_FCP_TARGET, + }; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); + if (!stor_device->rport) + goto err_out3; } #endif return 0; +err_out3: + scsi_remove_host(host); + err_out2: /* * Once we have connected with the host, we would need to @@ -1854,8 +1865,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] scsi: storvsc: Add support for FC rport.
On 04/03/2017 08:17 AM, Christoph Hellwig wrote: if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids = { + .roles = FC_PORT_ROLE_FCP_TARGET, + }; I don't think storvsc ever acts as FCP target. In order to implement the work around so that the scsi scan works indicating FC_PORT_ROLE_FCP_TARGET as a role was necessary due to its test in fc_scsi_scan_rport. The idea here is to avoid making any changes to the fc_transport driver which was of some concern. Thanks, Cathy ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 0/2] scsi: storvsc: Add support for FC rport
The updated patch set provides a way for drivers ( specifically storvsc in this case ) that expose virturalized fc devices but that do not expose rports to be manually scanned. This is done via creating a pseudo rport in storvsc and a corresponding dummy initiator rport role in the fc transport. Changes since v2: - Additional patch adding FC_PORT_ROLE_FCP_DUMMY_INITIATOR role to fc_transport - Changed storvsc rport role to FC_PORT_ROLE_FCP_DUMMY_INITIATOR Changes since v1: - Fix fc_rport_identifiers init [Stephen Hemminger] - Better error checking Cathy Avery (2): scsi: scsi_transport_fc: Add dummy initiator role to rport scsi: storvsc: Add support for FC rport. drivers/scsi/scsi_transport_fc.c | 10 ++ drivers/scsi/storvsc_drv.c | 23 ++- include/scsi/scsi_transport_fc.h | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 2/2] scsi: storvsc: Add support for FC rport.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. This patch stubs in an rport per fc_host and sets its rport role as FC_PORT_ROLE_FCP_DUMMY_INITIATOR to indicate to the fc_transport that it is a pseudo rport in order to scan the scsi stack via echo "- - -" > /sys/class/scsi_host/hostX/scan. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 016639d..1ec8579 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -476,6 +476,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1823,19 +1826,27 @@ static int storvsc_probe(struct hv_device *device, target = (device->dev_instance.b[5] << 8 | device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); - if (ret) { - scsi_remove_host(host); - goto err_out2; - } + if (ret) + goto err_out3; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids = { + .roles = FC_PORT_ROLE_FCP_DUMMY_INITIATOR, + }; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); + if (!stor_device->rport) + goto err_out3; } #endif return 0; +err_out3: + scsi_remove_host(host); + err_out2: /* * Once we have connected with the host, we would need to @@ -1861,8 +1872,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 1/2] scsi: scsi_transport_fc: Add dummy initiator role to rport
This patch allows scsi drivers that expose virturalized fibre channel devices but that do not expose rports to successfully rescan the scsi bus via echo "- - -" > /sys/class/scsi_host/hostX/scan. Drivers can create a pseudo rport and indicate FC_PORT_ROLE_FCP_DUMMY_INITIATOR as the rport's role in fc_rport_identifiers. This insures that a valid scsi_target_id is assigned to the newly created rport and it can meet the requirements of fc_user_scan_tgt calling scsi_scan_target. Signed-off-by: Cathy Avery --- drivers/scsi/scsi_transport_fc.c | 10 ++ include/scsi/scsi_transport_fc.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 2d753c9..de85602 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -289,9 +289,10 @@ static const struct { u32 value; char*name; } fc_port_role_names[] = { - { FC_PORT_ROLE_FCP_TARGET, "FCP Target" }, - { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, - { FC_PORT_ROLE_IP_PORT, "IP Port" }, + { FC_PORT_ROLE_FCP_TARGET, "FCP Target" }, + { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, + { FC_PORT_ROLE_IP_PORT, "IP Port" }, + { FC_PORT_ROLE_FCP_DUMMY_INITIATOR, "FCP Dummy Initiator" }, }; fc_bitfield_name_search(port_roles, fc_port_role_names) @@ -2628,7 +2629,8 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel, spin_lock_irqsave(shost->host_lock, flags); rport->number = fc_host->next_rport_number++; - if (rport->roles & FC_PORT_ROLE_FCP_TARGET) + if ((rport->roles & FC_PORT_ROLE_FCP_TARGET) || + (rport->roles & FC_PORT_ROLE_FCP_DUMMY_INITIATOR)) rport->scsi_target_id = fc_host->next_target_id++; else rport->scsi_target_id = -1; diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index b21b8aa5..6e208bb 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -162,6 +162,7 @@ enum fc_tgtid_binding_type { #define FC_PORT_ROLE_FCP_TARGET0x01 #define FC_PORT_ROLE_FCP_INITIATOR 0x02 #define FC_PORT_ROLE_IP_PORT 0x04 +#define FC_PORT_ROLE_FCP_DUMMY_INITIATOR 0x08 /* The following are for compatibility */ #define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] scsi: storvsc: Allow only one remove lun work item to be issued per lun
When running multipath on a VM if all available paths go down the driver can schedule large amounts of storvsc_remove_lun work items to the same lun. In response to the failing paths typically storvsc responds by taking host->scan_mutex and issuing a TUR per lun. If there has been heavy IO to the failed device all the failed IOs are returned from the host. A remove lun work item is issued per failed IO. If the outstanding TURs have not been completed in a timely manner the scan_mutex is never released or released too late. Consequently the many remove lun work items are not completed as scsi_remove_device also tries to take host->scan_mutex. This results in dragging the VM down and sometimes completely. This patch only allows one remove lun to be issued to a particular lun while it is an instantiated member of the scsi stack. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 33 +++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 016639d..9dbb5bf 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -478,6 +478,10 @@ struct storvsc_device { u64 port_name; }; +struct storvsc_dev_hostdata { + atomic_t req_remove_lun; +}; + struct hv_host_device { struct hv_device *dev; unsigned int port; @@ -918,6 +922,8 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, u8 asc, u8 ascq) { struct storvsc_scan_work *wrk; + struct storvsc_dev_hostdata *hostdata; + struct scsi_device *sdev; void (*process_err_fn)(struct work_struct *work); bool do_work = false; @@ -953,8 +959,17 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, } break; case SRB_STATUS_INVALID_LUN: - do_work = true; - process_err_fn = storvsc_remove_lun; + sdev = scsi_device_lookup(host, 0, vm_srb->target_id, + vm_srb->lun); + if (sdev) { + hostdata = sdev->hostdata; + if (hostdata && + !atomic_cmpxchg(&hostdata->req_remove_lun, 0, 1)) { + do_work = true; + process_err_fn = storvsc_remove_lun; + } + scsi_device_put(sdev); + } break; case SRB_STATUS_ABORTED: if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID && @@ -1426,9 +1441,22 @@ static int storvsc_device_configure(struct scsi_device *sdevice) sdevice->no_write_same = 0; } + sdevice->hostdata = kzalloc(sizeof(struct storvsc_dev_hostdata), + GFP_ATOMIC); + if (!sdevice->hostdata) + return -ENOMEM; + return 0; } +static void storvsc_device_destroy(struct scsi_device *sdevice) +{ + if (sdevice->hostdata) { + kfree(sdevice->hostdata); + sdevice->hostdata = NULL; + } +} + static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, sector_t capacity, int *info) { @@ -1669,6 +1697,7 @@ static struct scsi_host_template scsi_driver = { .eh_timed_out = storvsc_eh_timed_out, .slave_alloc = storvsc_device_alloc, .slave_configure = storvsc_device_configure, + .slave_destroy =storvsc_device_destroy, .cmd_per_lun = 255, .this_id = -1, .use_clustering = ENABLE_CLUSTERING, -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 1/2] scsi: scsi_transport_fc: Add dummy initiator role to rport
This patch allows scsi drivers that expose virturalized fibre channel devices but that do not expose rports to successfully rescan the scsi bus via echo "- - -" > /sys/class/scsi_host/hostX/scan. Drivers can create a pseudo rport and indicate FC_PORT_ROLE_FCP_DUMMY_INITIATOR as the rport's role in fc_rport_identifiers. This insures that a valid scsi_target_id is assigned to the newly created rport and it can meet the requirements of fc_user_scan_tgt calling scsi_scan_target. Signed-off-by: Cathy Avery --- drivers/scsi/scsi_transport_fc.c | 10 ++ include/scsi/scsi_transport_fc.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 2d753c9..de85602 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -289,9 +289,10 @@ static const struct { u32 value; char*name; } fc_port_role_names[] = { - { FC_PORT_ROLE_FCP_TARGET, "FCP Target" }, - { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, - { FC_PORT_ROLE_IP_PORT, "IP Port" }, + { FC_PORT_ROLE_FCP_TARGET, "FCP Target" }, + { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, + { FC_PORT_ROLE_IP_PORT, "IP Port" }, + { FC_PORT_ROLE_FCP_DUMMY_INITIATOR, "FCP Dummy Initiator" }, }; fc_bitfield_name_search(port_roles, fc_port_role_names) @@ -2628,7 +2629,8 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel, spin_lock_irqsave(shost->host_lock, flags); rport->number = fc_host->next_rport_number++; - if (rport->roles & FC_PORT_ROLE_FCP_TARGET) + if ((rport->roles & FC_PORT_ROLE_FCP_TARGET) || + (rport->roles & FC_PORT_ROLE_FCP_DUMMY_INITIATOR)) rport->scsi_target_id = fc_host->next_target_id++; else rport->scsi_target_id = -1; diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index b21b8aa5..6e208bb 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -162,6 +162,7 @@ enum fc_tgtid_binding_type { #define FC_PORT_ROLE_FCP_TARGET0x01 #define FC_PORT_ROLE_FCP_INITIATOR 0x02 #define FC_PORT_ROLE_IP_PORT 0x04 +#define FC_PORT_ROLE_FCP_DUMMY_INITIATOR 0x08 /* The following are for compatibility */ #define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 0/2] scsi: storvsc: Add support for FC rport
The updated patch set provides a way for drivers ( specifically storvsc in this case ) that expose virturalized fc devices but that do not expose rports to be manually scanned. This is done via creating a pseudo rport in storvsc and a corresponding dummy initiator rport role in the fc transport. Changes since v2: - Additional patch adding FC_PORT_ROLE_FCP_DUMMY_INITIATOR role to fc_transport - Changed storvsc rport role to FC_PORT_ROLE_FCP_DUMMY_INITIATOR Changes since v1: - Fix fc_rport_identifiers init [Stephen Hemminger] - Better error checking Cathy Avery (2): scsi: scsi_transport_fc: Add dummy initiator role to rport scsi: storvsc: Add support for FC rport. drivers/scsi/scsi_transport_fc.c | 10 ++ drivers/scsi/storvsc_drv.c | 23 ++- include/scsi/scsi_transport_fc.h | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 2/2] scsi: storvsc: Add support for FC rport.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. The driver also attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. Current customer tools running on the VM require that these names be available in the well known standard location under fc_host/hostX. This patch stubs in an rport per fc_host and sets its rport role as FC_PORT_ROLE_FCP_DUMMY_INITIATOR to indicate to the fc_transport that it is a pseudo rport in order to scan the scsi stack via echo "- - -" > /sys/class/scsi_host/hostX/scan. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 016639d..1ec8579 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -476,6 +476,9 @@ struct storvsc_device { */ u64 node_name; u64 port_name; +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) + struct fc_rport *rport; +#endif }; struct hv_host_device { @@ -1823,19 +1826,27 @@ static int storvsc_probe(struct hv_device *device, target = (device->dev_instance.b[5] << 8 | device->dev_instance.b[4]); ret = scsi_add_device(host, 0, target, 0); - if (ret) { - scsi_remove_host(host); - goto err_out2; - } + if (ret) + goto err_out3; } #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) if (host->transportt == fc_transport_template) { + struct fc_rport_identifiers ids = { + .roles = FC_PORT_ROLE_FCP_DUMMY_INITIATOR, + }; + fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; + stor_device->rport = fc_remote_port_add(host, 0, &ids); + if (!stor_device->rport) + goto err_out3; } #endif return 0; +err_out3: + scsi_remove_host(host); + err_out2: /* * Once we have connected with the host, we would need to @@ -1861,8 +1872,10 @@ static int storvsc_remove(struct hv_device *dev) struct Scsi_Host *host = stor_device->host; #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (host->transportt == fc_transport_template) + if (host->transportt == fc_transport_template) { + fc_remote_port_delete(stor_device->rport); fc_remove_host(host); + } #endif scsi_remove_host(host); storvsc_dev_remove(dev); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] scsi: storvsc: Allow only one remove lun work item to be issued per lun
On 04/15/2017 10:06 AM, Christoph Hellwig wrote: Just add a singlethreaded workqueue for storvsc_handle_error and you'll get serialization for all error handling for free. The problem I am seeing is that many work items can be queued up for the same lun before it goes away. The single threaded queue would have to allow for only a queue of one and no more. Either that or each work item for a particular lun must have the same memory address so it gets rejected if it you try to queue a remove to the same lun twice. Maybe I am not understanding your suggestion correctly. Thanks, Cathy ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] Drivers: hv: kvp: fix IP Failover
t if VersionAndFeatures.HypervisorPresent * is set by CPUID(HVCPUID_VERSION_FEATURES). */ Acked-by: Cathy Avery ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] Drivers: hv: kvp: fix IP Failover
Sorry acking wrong email. Thanks, Cathy On 03/30/2016 08:21 AM, Cathy Avery wrote: On 03/29/2016 08:30 AM, Vitaly Kuznetsov wrote: Hyper-V VMs can be replicated to another hosts and there is a feature to set different IP for replicas, it is called 'Failover TCP/IP'. When such guest starts Hyper-V host sends it KVP_OP_SET_IP_INFO message as soon as we finish negotiation procedure. The problem is that it can happen (and it actually happens) before userspace daemon connects and we reply with HV_E_FAIL to the message. As there are no repetitions we fail to set the requested IP. Solve the issue by postponing our reply to the negotiation message till userspace daemon is connected. We can't wait too long as there is a host-side timeout (cca. 75 seconds) and if we fail to reply in this time frame the whole KVP service will become inactive. The solution is not ideal - if it takes userspace daemon more than 60 seconds to connect IP Failover will still fail but I don't see a solution with our current separation between kernel and userspace parts. Other two modules (VSS and FCOPY) don't require such delay, leave them untouched. Signed-off-by: Vitaly Kuznetsov --- Changes since v1: - Cancel handshake timeout work on module unload. --- drivers/hv/hv_kvp.c | 31 +++ drivers/hv/hyperv_vmbus.h | 5 + 2 files changed, 36 insertions(+) diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 9b9b370..cb1a916 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -78,9 +78,11 @@ static void kvp_send_key(struct work_struct *dummy); static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error); static void kvp_timeout_func(struct work_struct *dummy); +static void kvp_host_handshake_func(struct work_struct *dummy); static void kvp_register(int); static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func); +static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func); static DECLARE_WORK(kvp_sendkey_work, kvp_send_key); static const char kvp_devname[] = "vmbus/hv_kvp"; @@ -130,6 +132,11 @@ static void kvp_timeout_func(struct work_struct *dummy) hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); } +static void kvp_host_handshake_func(struct work_struct *dummy) +{ +hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback); +} + static int kvp_handle_handshake(struct hv_kvp_msg *msg) { switch (msg->kvp_hdr.operation) { @@ -154,6 +161,12 @@ static int kvp_handle_handshake(struct hv_kvp_msg *msg) pr_debug("KVP: userspace daemon ver. %d registered\n", KVP_OP_REGISTER); kvp_register(dm_reg_value); + +/* + * If we're still negotiating with the host cancel the timeout + * work to not poll the channel twice. + */ +cancel_delayed_work_sync(&kvp_host_handshake_work); hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); return 0; @@ -594,7 +607,22 @@ void hv_kvp_onchannelcallback(void *context) struct icmsg_negotiate *negop = NULL; int util_fw_version; int kvp_srv_version; +static enum {NEGO_NOT_STARTED, + NEGO_IN_PROGRESS, + NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED; +if (host_negotiatied == NEGO_NOT_STARTED && +kvp_transaction.state < HVUTIL_READY) { +/* + * If userspace daemon is not connected and host is asking + * us to negotiate we need to delay to not lose messages. + * This is important for Failover IP setting. + */ +host_negotiatied = NEGO_IN_PROGRESS; +schedule_delayed_work(&kvp_host_handshake_work, + HV_UTIL_NEGO_TIMEOUT * HZ); +return; +} if (kvp_transaction.state > HVUTIL_READY) return; @@ -672,6 +700,8 @@ void hv_kvp_onchannelcallback(void *context) vmbus_sendpacket(channel, recv_buffer, recvlen, requestid, VM_PKT_DATA_INBAND, 0); + +host_negotiatied = NEGO_FINISHED; } } @@ -708,6 +738,7 @@ hv_kvp_init(struct hv_util_service *srv) void hv_kvp_deinit(void) { kvp_transaction.state = HVUTIL_DEVICE_DYING; +cancel_delayed_work_sync(&kvp_host_handshake_work); cancel_delayed_work_sync(&kvp_timeout_work); cancel_work_sync(&kvp_sendkey_work); hvutil_transport_destroy(hvt); diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 12321b9..8b07f9c 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -36,6 +36,11 @@ #define HV_UTIL_TIMEOUT 30 /* + * Timeout for guest-host handshake for services. + */ +#define HV_UTIL_NEGO_TIMEOUT 60 + +/* * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent * is set by CPUID(HVCPUID_VERSION_FEATURES). */ Acked-b
Re: [PATCH v8 net-next 1/1] hv_sock: introduce Hyper-V Sockets
Hi, I will be working with Dexuan to possibly port this functionality into RHEL. Here are my initial comments. Mostly stylistic. They are prefaced by CAA. Thanks, Cathy Avery On 04/07/2016 09:36 PM, Dexuan Cui wrote: Hyper-V Sockets (hv_sock) supplies a byte-stream based communication mechanism between the host and the guest. It's somewhat like TCP over VMBus, but the transportation layer (VMBus) is much simpler than IP. With Hyper-V Sockets, applications between the host and the guest can talk to each other directly by the traditional BSD-style socket APIs. Hyper-V Sockets is only available on new Windows hosts, like Windows Server 2016. More info is in this article "Make your own integration services": https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/develop/make_mgmt_service The patch implements the necessary support in the guest side by introducing a new socket address family AF_HYPERV. Signed-off-by: Dexuan Cui Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Vitaly Kuznetsov --- MAINTAINERS |2 + include/linux/hyperv.h | 16 + include/linux/socket.h |5 +- include/net/af_hvsock.h | 51 ++ include/uapi/linux/hyperv.h | 25 + net/Kconfig |1 + net/Makefile|1 + net/hv_sock/Kconfig | 10 + net/hv_sock/Makefile|3 + net/hv_sock/af_hvsock.c | 1483 +++ 10 files changed, 1595 insertions(+), 2 deletions(-) create mode 100644 include/net/af_hvsock.h create mode 100644 net/hv_sock/Kconfig create mode 100644 net/hv_sock/Makefile create mode 100644 net/hv_sock/af_hvsock.c diff --git a/MAINTAINERS b/MAINTAINERS index 67d99dd..7b6f203 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5267,7 +5267,9 @@ F:drivers/pci/host/pci-hyperv.c F:drivers/net/hyperv/ F:drivers/scsi/storvsc_drv.c F:drivers/video/fbdev/hyperv_fb.c +F: net/hv_sock/ F:include/linux/hyperv.h +F: include/net/af_hvsock.h F:tools/hv/ F:Documentation/ABI/stable/sysfs-bus-vmbus diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index aa0fadc..b92439d 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1338,4 +1338,20 @@ extern __u32 vmbus_proto_version; int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id, const uuid_le *shv_host_servie_id); +struct vmpipe_proto_header { + u32 pkt_type; + u32 data_size; +} __packed; + +#define HVSOCK_HEADER_LEN (sizeof(struct vmpacket_descriptor) + \ +sizeof(struct vmpipe_proto_header)) + +/* See 'prev_indices' in hv_ringbuffer_read(), hv_ringbuffer_write() */ +#define PREV_INDICES_LEN (sizeof(u64)) + +#define HVSOCK_PKT_LEN(payload_len)(HVSOCK_HEADER_LEN + \ + ALIGN((payload_len), 8) + \ + PREV_INDICES_LEN) +#define HVSOCK_MIN_PKT_LEN HVSOCK_PKT_LEN(1) + #endif /* _HYPERV_H */ diff --git a/include/linux/socket.h b/include/linux/socket.h index 73bf6c6..88b1ccd 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -201,8 +201,8 @@ struct ucred { #define AF_NFC39 /* NFC sockets */ #define AF_VSOCK 40 /* vSockets */ #define AF_KCM41 /* Kernel Connection Multiplexor*/ - -#define AF_MAX 42 /* For now.. */ +#define AF_HYPERV 42 /* Hyper-V Sockets */ +#define AF_MAX 43 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -249,6 +249,7 @@ struct ucred { #define PF_NFCAF_NFC #define PF_VSOCK AF_VSOCK #define PF_KCMAF_KCM +#define PF_HYPERV AF_HYPERV #define PF_MAXAF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/include/net/af_hvsock.h b/include/net/af_hvsock.h new file mode 100644 index 000..a5aa28d --- /dev/null +++ b/include/net/af_hvsock.h @@ -0,0 +1,51 @@ +#ifndef __AF_HVSOCK_H__ +#define __AF_HVSOCK_H__ + +#include +#include +#include + +#define VMBUS_RINGBUFFER_SIZE_HVSOCK_RECV (5 * PAGE_SIZE) +#define VMBUS_RINGBUFFER_SIZE_HVSOCK_SEND (5 * PAGE_SIZE) + +#define HVSOCK_RCV_BUF_SZ VMBUS_RINGBUFFER_SIZE_HVSOCK_RECV +#define HVSOCK_SND_BUF_SZ PAGE_SIZE + +#define sk_to_hvsock(__sk)((struct hvsock_sock *)(__sk)) +#define hvsock_to_sk(__hvsk) ((struct sock *)(__hvsk)) + +struct hvsock_sock { + /* sk must be the first member. */ + struct sock sk; + + struct sockaddr_hv local_addr; + struct sockaddr_hv remote_addr; + + /* protected by the global hvsock_mutex */ + struct list_head bound_list; + struct list_head connected_list; + + struct list_head accept_qu
[PATCH 1/1] scsi: storvsc: Filter out storvsc messages CD-ROM medium not present
When a virtual scsi DVD device is present with no image file attached the storvsc driver logs all resulting unnecessary sense errors whenever IO is issued to the device. [storvsc] Sense Key : Not Ready [current] [storvsc] Add. Sense: Medium not present - tray closed Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 3ddcabb..f0efa07 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -966,7 +966,9 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr) && - do_logging(STORVSC_LOGGING_ERROR)) + !(sense_hdr.sense_key == NOT_READY && +sense_hdr.asc == 0x03A) && + do_logging(STORVSC_LOGGING_ERROR)) scsi_print_sense_hdr(scmnd->device, "storvsc", &sense_hdr); } -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] pci-hyperv: use kmalloc to allocate hypercall params buffer
Hi, Is the double semicolon a typo? Thanks, Cathy diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 763ff87..ca553df 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -378,6 +378,8 @@ struct hv_pcibus_device { struct msi_domain_info msi_info; struct msi_controller msi_chip; struct irq_domain *irq_domain; + struct retarget_msi_interrupt retarget_msi_interrupt_params; + spinlock_t retarget_msi_interrupt_lock;; }; On 11/29/2016 06:25 PM, Bjorn Helgaas wrote: On Tue, Nov 08, 2016 at 02:04:38PM -0800, Long Li wrote: From: Long Li hv_do_hypercall assumes that we pass a segment from a physically continuous buffer. Buffer allocated on the stack may not work if CONFIG_VMAP_STACK=y is set. Change to use kmalloc to allocate this buffer. The v2 patch adds locking to access the pre-allocated buffer. Signed-off-by: Long Li Reported-by: Haiyang Zhang Applied with KY's ack to pci/host-hv, thanks! --- drivers/pci/host/pci-hyperv.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 763ff87..ca553df 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -378,6 +378,8 @@ struct hv_pcibus_device { struct msi_domain_info msi_info; struct msi_controller msi_chip; struct irq_domain *irq_domain; + struct retarget_msi_interrupt retarget_msi_interrupt_params; + spinlock_t retarget_msi_interrupt_lock;; }; /* @@ -774,34 +776,40 @@ void hv_irq_unmask(struct irq_data *data) { struct msi_desc *msi_desc = irq_data_get_msi_desc(data); struct irq_cfg *cfg = irqd_cfg(data); - struct retarget_msi_interrupt params; + struct retarget_msi_interrupt *params; struct hv_pcibus_device *hbus; struct cpumask *dest; struct pci_bus *pbus; struct pci_dev *pdev; int cpu; + unsigned long flags; dest = irq_data_get_affinity_mask(data); pdev = msi_desc_to_pci_dev(msi_desc); pbus = pdev->bus; hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); - memset(¶ms, 0, sizeof(params)); - params.partition_id = HV_PARTITION_ID_SELF; - params.source = 1; /* MSI(-X) */ - params.address = msi_desc->msg.address_lo; - params.data = msi_desc->msg.data; - params.device_id = (hbus->hdev->dev_instance.b[5] << 24) | + spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags); + + params = &hbus->retarget_msi_interrupt_params; + memset(params, 0, sizeof(*params)); + params->partition_id = HV_PARTITION_ID_SELF; + params->source = 1; /* MSI(-X) */ + params->address = msi_desc->msg.address_lo; + params->data = msi_desc->msg.data; + params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | (hbus->hdev->dev_instance.b[4] << 16) | (hbus->hdev->dev_instance.b[7] << 8) | (hbus->hdev->dev_instance.b[6] & 0xf8) | PCI_FUNC(pdev->devfn); - params.vector = cfg->vector; + params->vector = cfg->vector; for_each_cpu_and(cpu, dest, cpu_online_mask) - params.vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu)); + params->vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu)); + + hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, params, NULL); - hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, ¶ms, NULL); + spin_unlock_irqrestore(&hbus->retarget_msi_interrupt_lock, flags); pci_msi_unmask_irq(data); } @@ -2186,6 +2194,7 @@ static int hv_pci_probe(struct hv_device *hdev, INIT_LIST_HEAD(&hbus->resources_for_children); spin_lock_init(&hbus->config_lock); spin_lock_init(&hbus->device_list_lock); + spin_lock_init(&hbus->retarget_msi_interrupt_lock); sema_init(&hbus->enum_sem, 1); init_completion(&hbus->remove_event); -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[RFC PATCH] scsi: scsi_transport_fc: Create a lightweight option for Virtual FC Hosts.
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; +
[PATCH 0/2] scsi: Create a lightweight FC Transport option for Virtual FC Hosts.
Currently virtual FC hosts or lightweight hosts are not able to be manually scanned via sysfs due to the fact that they do not contain the complete characteristic set associated with a normal FC host ( missing rports, vports, etc ) and are not consistent with the current FC transport model. Patch 1: The patch provides 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. Patch 2: storvsc elects using the new lightweight FC host option. Cathy Avery (2): scsi: scsi_transport_fc: Provide a lightweight option for Virtual FC Hosts. scsi: storvsc: Add support for FC lightweight host. 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(-) -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] scsi: scsi_transport_fc: Provide a lightweight option for Virtual FC Hosts.
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) { s
[PATCH 2/2] scsi: storvsc: Add support for FC lightweight host.
Enable FC lightweight host option so that the luns exposed by the driver may be manually scanned. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) 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); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] scsi: storvsc: Add support for FC lightweight host.
On 01/18/2017 06:15 PM, Dan Carpenter wrote: On Wed, Jan 18, 2017 at 03:28:58PM -0500, Cathy Avery wrote: Enable FC lightweight host option so that the luns exposed by the driver may be manually scanned. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) 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; I don't undestand how removing this is related. Its not related but it is also not necessary so I took it out. The default scsi timeout handler will be used. I can certainly put it back. Cathy regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/2] scsi: scsi_transport_fc: Provide a lightweight option for Virtual FC Hosts.
On 01/19/2017 10:11 AM, Christoph Hellwig wrote: On Wed, Jan 18, 2017 at 03:28:57PM -0500, Cathy Avery wrote: 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. This need some really good documentation in the code and changelog what "lightweight" means. It's a pretty horrible term, btw. Thanks, I will work on better documentation and a better name. Cathy ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] scsi: storvsc: Add support for FC lightweight host.
I'm sorry. In my zeal to push out this patch I have done a poor job of communication on a number of levels. The first patch which deals with the fc transport changes will not set the scsi_transport_template.eh_timed_out function directly during lightweight fc_attach_transport(). It instead relies on whatever was indicated as the scsi_host_template timeout handler during inscsi_times_out() scsi_error.c. So yes in a sense it is related but now I believe I understand your point. Perhaps this would fall more under the heading of post fc_transport implementation storvsc cleanup necessitating its own patch. I will break it out in the next go round. Thanks, Cathy On 01/20/2017 04:31 AM, Dan Carpenter wrote: On Thu, Jan 19, 2017 at 12:55:27PM -0500, Cathy Avery wrote: On 01/18/2017 06:15 PM, Dan Carpenter wrote: On Wed, Jan 18, 2017 at 03:28:58PM -0500, Cathy Avery wrote: Enable FC lightweight host option so that the luns exposed by the driver may be manually scanned. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) 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; I don't undestand how removing this is related. Its not related but it is also not necessary so I took it out. The default scsi timeout handler will be used. I can certainly put it back. I'm not sure that we understand each other properly. Has this patch already been committed? If so, then there is no need to put it back. But it if hasn't been committed, can you resend the patches with that bit broken out into a separate patch with its own changelog? Patches should only do one thing but you're saying that it's doing two unrelated things. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] scsi: storvsc: Add support for FC lightweight host.
Hi, There is no way to issue a lip directly as the current client for this feature ( storvsc ) does not handle that request as a physical fc hba can. Storvsc only has two fc attributes exposed - port_name and node_name. You can rescan the bus with the standard echo "- - -" > /sys/class/scsi_host/hostX/scan. Cathy On 01/22/2017 10:13 PM, Fam Zheng wrote: On Wed, 01/18 15:28, Cathy Avery wrote: Enable FC lightweight host option so that the luns exposed by the driver may be manually scanned. Hi Cathy, out of curiosity: how does this relate to issue_lip operation? And how to trigger manual scan with this patch? Fam ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 0/2] scsi: storvsc: Add support for FC lightweight host.
This patch set is based on the following patch submission and email exchange: [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 Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. This was done to provide an interface for existing customer tools that was more consistent with a conventional FC device. The driver attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the virtualized nature of the FC host ( missing rports, vports, etc ). At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot. The patch above attempted to address the problem of not being able to scan FC hosts on a Hyper-V guest by setting fc_transport_template->user_scan = NULL but it was rejected in favor of a new "lightweight" version of the FC transport that only provides the bare minimum functionality of the standard FC model. This new transport option would be more suitable for FC transports running on a VM and provide some flexibility in the future. The patches below offer a method to incorporate the new lightweight FC option into the existing transport and storvsc drivers. Patch 1: scsi_transport_fc.h, scsi_transport_fc.c 1) Adds the lightweight_transport option to fc_function_template. Based on this selection the transport will either be lightweight or default to heavyweight. 2) Divides the applicable export functions into two sets. The lightweight functions involve FC attributes port_name and node name. The functions that deal with targets, rports, etc are not used. The heavyweight default contains the original standard physical FC hba attribute set. 3) All top level FC class directories such fc_remote_ports, fc_transport, and fc_vports are still created when the transport driver is loaded. They are just not populated when running in lightweight mode. Conceptually both lightweight and heavyweight clients could coexist. 4) fc_transport_template->user_scan is now null and the bus can be scanned. Patch 2: storvsc.c 1) storvsc elects to use the new lightweight FC host option by enabling it in fc_function_template. 2) Removes an original workaround dealing with replacing the eh_timed_out function. Patch 1 will not set the scsi_transport_template.eh_timed_out function directly during lightweight fc_attach_transport(). It instead relies on whatever was indicated as the scsi_host_template timeout handler during scsi_times_out() scsi_error.c. So the workaround is no longer necessary. It has been suggested that the word lightweight may not be the best choice of terms when describing the new FC transport option. I can offer a few new ones but I am not particularly imaginative. Virtual FC Mini FC Host only FC Changes from V1: Added more comments and documentation in the code regarding the lightweight feature. Cathy Avery (2): scsi: scsi_transport_fc: Provide a lightweight option for Virtual FC Hosts. scsi: storvsc: Add support for FC lightweight host. drivers/scsi/scsi_transport_fc.c | 144 +-- drivers/scsi/storvsc_drv.c | 12 ++-- include/scsi/scsi_transport_fc.h | 2 + 3 files changed, 149 insertions(+), 9 deletions(-) -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 1/2] scsi: scsi_transport_fc: Provide a lightweight option for Virtual FC Hosts.
This patch provides a means to offer a lightweight option to the current FC transport class. This new transport option is more suitable for FC transports running on a VM that virtualizes their FCs and that do not possess rports or vports whereas the heavyweight option maintains the standard physical FC hba attuibute set. The patch performs the following: 1) Adds the lightweight_transport option to fc_function_template. Based on this selection the transport will either be lightweight or default to heavyweight. 2) Divides the applicable export functions into two sets. The lightweight functions involve FC attributes port_name and node name. The functions that deal with targets, rports, etc are not used. The heavyweight default contains the original standard physical FC hba attribute set. 3) All top level FC class directories such fc_remote_ports, fc_transport, and fc_vports are still created when the transport driver loads. They are just not populated when running in lightweight mode. Conceptually both lightweight and heavyweight clients could coexist. 4) fc_transport_template->user_scan is now null and the bus can be scanned. Signed-off-by: Cathy Avery --- drivers/scsi/scsi_transport_fc.c | 144 +-- include/scsi/scsi_transport_fc.h | 2 + 2 files changed, 142 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 03577bd..615057c 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -52,6 +52,25 @@ static void fc_bsg_remove(struct request_queue *); static void fc_bsg_goose_queue(struct fc_rport *); /* + * These functions define the actions taken on behalf of either + * a virtualized client which is considered to be lightweigth + * having only port name and node name as attributes in sysfs and + * which does not possess rports or vports vs the heavyweigth + * mode which is intended for fully functional clients such as + * physical HBAs. + */ + +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 +371,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 +410,33 @@ 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); + + /* +* Check if the client driver has selected a minimum set +* of fc transport attributes to initialize. Otherwise +* initialize all currently available attributes. +*/ + + 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) +{ + /* Only node_name and port_name are used */ + 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 +517,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 +2233,51 @@ 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_l
[PATCH v2 2/2] scsi: storvsc: Add support for FC lightweight host.
Included in the current storvsc driver for Hyper-V is the ability to access luns on an FC fabric via a virtualized fiber channel adapter exposed by the Hyper-V host. This was done to provide an interface for existing customer tools that was more consistent with a conventional FC device. The driver attaches to the FC transport to allow host and port names to be published under /sys/class/fc_host/hostX. A problem arose when attaching to the FC transport. The scsi_scan code attempts to call fc_user_scan which has basically become a no-op due to the virtualized nature of the FC host ( missing rports, vports, etc ). At this point you cannot refresh the scsi bus after mapping or unmapping luns on the SAN without a reboot. This patch consists of: 1) storvsc elects to use the new lightweight FC host option by enabling it in fc_function_template facilitating a fuctional scsi_scan. 2) Removes an original workaround dealing with replacing the eh_timed_out function. Patch 1 will not set the scsi_transport_template.eh_timed_out function directly during lightweight fc_attach_transport(). It instead relies on whatever was indicated as the scsi_host_template timeout handler during scsi_times_out() scsi_error.c. So the workaround is no longer necessary. Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 888e16e..d487e00 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1878,10 +1878,17 @@ static struct hv_driver storvsc_drv = { .remove = storvsc_remove, }; +/* + * The driver cannot functionally back all transport + * attributes so select only those pertinent including + * the lightweight model. + */ + #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) static struct fc_function_template fc_transport_functions = { .show_host_node_name = 1, .show_host_port_name = 1, + .lightweight_transport = 1, }; #endif @@ -1906,11 +1913,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); -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v15 net-next 1/1] hv_sock: introduce Hyper-V Sockets
It's too bad about having to allocate the send/receive rings on a per socket basis. Hopefully this will change in the future. I have built kernel 4.7.0-rc6 with this patch and did a quick test on the driver using rhel7 over hyperv Windows Server 2016 TP5. These were basic send and receive tests ( host to vm and vm to host ) using apps provided by Dexuan. Reviewed-by: Cathy Avery Tested-by: Cathy Avery On 07/08/2016 03:47 AM, Dexuan Cui wrote: Hyper-V Sockets (hv_sock) supplies a byte-stream based communication mechanism between the host and the guest. It's somewhat like TCP over VMBus, but the transportation layer (VMBus) is much simpler than IP. With Hyper-V Sockets, applications between the host and the guest can talk to each other directly by the traditional BSD-style socket APIs. Hyper-V Sockets is only available on new Windows hosts, like Windows Server 2016. More info is in this article "Make your own integration services": https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/develop/make_mgmt_service The patch implements the necessary support in the guest side by introducing a new socket address family AF_HYPERV. Signed-off-by: Dexuan Cui Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Vitaly Kuznetsov Cc: Cathy Avery --- You can also get the patch here (2764221d): https://github.com/dcui/linux/commits/decui/hv_sock/net-next/20160708_v15 For the change log before v12, please see https://lkml.org/lkml/2016/5/15/31 In v12, the changes are mainly the following: 1) remove the module params as David suggested. 2) use 5 exact pages for VMBus send/recv rings, respectively. The host side's design of the feature requires 5 exact pages for recv/send rings respectively -- this is suboptimal considering memory consumption, however unluckily we have to live with it, before the host comes up with a new design in the future. :-( 3) remove the per-connection static send/recv buffers Instead, we allocate and free the buffers dynamically only when we recv/send data. This means: when a connection is idle, no memory is consumed as recv/send buffers at all. In v13: I return ENOMEM on buffer alllocation failure Actually "man read/write" says "Other errors may occur, depending on the object connected to fd". "man send/recv" indeed lists ENOMEM. Considering AF_HYPERV is a new socket type, ENOMEM seems OK here. In the long run, I think we should add a new API in the VMBus driver, allowing data copy from VMBus ringbuffer into user mode buffer directly. This way, we can even eliminate this temporary buffer. In v14: fix some coding style issues pointed out by David. In v15: Just some stylistic changes addressing comments from Joe Perches and Olaf Hering -- thank you! - add a GPL blurb. - define a new macro PAGE_SIZE_4K and use it to replace PAGE_SIZE - change sk_to_hvsock/hvsock_to_sk() from macros to inline functions - remove a not-very-useful pr_err() - fix some typos in comment and coding style issues. Looking forward to your comments! MAINTAINERS |2 + include/linux/hyperv.h | 13 + include/linux/socket.h |4 +- include/net/af_hvsock.h | 78 +++ include/uapi/linux/hyperv.h | 24 + net/Kconfig |1 + net/Makefile|1 + net/hv_sock/Kconfig | 10 + net/hv_sock/Makefile|3 + net/hv_sock/af_hvsock.c | 1523 +++ 10 files changed, 1658 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 50f69ba..6eaa26f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5514,7 +5514,9 @@ F:drivers/pci/host/pci-hyperv.c F:drivers/net/hyperv/ F:drivers/scsi/storvsc_drv.c F:drivers/video/fbdev/hyperv_fb.c +F: net/hv_sock/ F:include/linux/hyperv.h +F: include/net/af_hvsock.h F:tools/hv/ F:Documentation/ABI/stable/sysfs-bus-vmbus diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 50f493e..1cda6ea5 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1508,5 +1508,18 @@ static inline void commit_rd_index(struct vmbus_channel *channel) vmbus_set_event(channel); } +struct vmpipe_proto_header { + u32 pkt_type; + u32 data_size; +}; + +#define HVSOCK_HEADER_LEN (sizeof(struct vmpacket_descriptor) + \ +sizeof(struct vmpipe_proto_header)) + +/* See 'prev_indices' in hv_ringbuffer_read(), hv_ringbuffer_write() */ +#define PREV_INDICES_LEN (sizeof(u64)) +#define HVSOCK_PKT_LEN(payload_len) (HVSOCK_HEADER_LEN + \ + ALIGN((payload_len), 8) + \ + PREV_INDICES_LEN) #endif /* _HYPERV_H */ diff --git a/include/linux/socket.h b/include/linux/socket.h index b5cc5a6..0b68b58 100644 --- a/include/linux/socket.h +++ b/i
[PATCH] PCI: hv: Fix interrupt cleanup path
SR-IOV disabled from the host causes a memory leak. pci-hyperv usually first receives a PCI_EJECT notification and then proceeds to delete the hpdev list entry in hv_eject_device_work(). Later in hv_msi_free() since the device is no longer on the device list hpdev is NULL and hv_msi_free returns without freeing int_desc as part of hv_int_desc_free(). Signed-off-by: Cathy Avery --- drivers/pci/host/pci-hyperv.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 7e9b2de..449d053 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -732,16 +732,18 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info, pdev = msi_desc_to_pci_dev(msi); hbus = info->data; - hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn)); - if (!hpdev) + int_desc = irq_data_get_irq_chip_data(irq_data); + if (!int_desc) return; - int_desc = irq_data_get_irq_chip_data(irq_data); - if (int_desc) { - irq_data->chip_data = NULL; - hv_int_desc_free(hpdev, int_desc); + irq_data->chip_data = NULL; + hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn)); + if (!hpdev) { + kfree(int_desc); + return; } + hv_int_desc_free(hpdev, int_desc); put_pcichild(hpdev, hv_pcidev_ref_by_slot); } -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/2 v2] pci-hyperv: properly handle pci bus remove
Hi, You seem to be missing the Reported-by tag. That's xiaof...@redhat.com. Cathy On 09/14/2016 10:10 PM, Long Li wrote: From: Long Li hv_pci_devices_present is called in hv_pci_remove when we remove a PCI device from host (e.g. by disabling SRIOV on a device). In hv_pci_remove, the bus is already removed before the call, so we don't need to rescan the bus in the workqueue scheduled from hv_pci_devices_present. By introducing status hv_pcibus_removed, we can avoid this situation. The patch fixes the following kernel panic. [ 383.853124] Workqueue: events pci_devices_present_work [pci_hyperv] [ 383.853124] task: 88007f5f8000 ti: 88007f60 task.ti: 88007f60 [ 383.853124] RIP: 0010:[] [] pci_is_pcie+0x6/0x20 [ 383.853124] RSP: 0018:88007f603d38 EFLAGS: 00010206 [ 383.853124] RAX: 88007f5f8000 RBX: 642f3d4854415056 RCX: 88007f603fd8 [ 383.853124] RDX: RSI: RDI: 642f3d4854415056 [ 383.853124] RBP: 88007f603d68 R08: 0246 R09: a045eb9e [ 383.853124] R10: 88007b419a80 R11: ea0001c0ef40 R12: 880003ee1c00 [ 383.853124] R13: 63702f30303a3137 R14: R15: 0246 [ 383.853124] FS: () GS:88007b40() knlGS: [ 383.853124] CS: 0010 DS: ES: CR0: 80050033 [ 383.853124] CR2: 7f68b3f52350 CR3: 03546000 CR4: 000406f0 [ 383.853124] DR0: DR1: DR2: [ 383.853124] DR3: DR6: 0ff0 DR7: 0400 [ 383.853124] Stack: [ 383.853124] 88007f603d68 8134db17 0008 880003ee1c00 [ 383.853124] 63702f30303a3137 880003d8edb8 88007f603da0 8134ee2d [ 383.853124] 880003d8ed00 88007f603dd8 880075fec320 880003d8edb8 [ 383.853124] Call Trace: [ 383.853124] [] ? pci_scan_slot+0x27/0x140 [ 383.853124] [] pci_scan_child_bus+0x3d/0x150 [ 383.853124] [] pci_devices_present_work+0x3ea/0x400 [pci_hyperv] [ 383.853124] [] process_one_work+0x17b/0x470 [ 383.853124] [] worker_thread+0x126/0x410 [ 383.853124] [] ? rescuer_thread+0x460/0x460 [ 383.853124] [] kthread+0xcf/0xe0 [ 383.853124] [] ? kthread_create_on_node+0x140/0x140 [ 383.853124] [] ret_from_fork+0x58/0x90 [ 383.853124] [] ? kthread_create_on_node+0x140/0x140 [ 383.853124] Code: 89 e5 5d 25 f0 00 00 00 c1 f8 04 c3 66 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 0f b6 47 4a 48 89 e5 5d c3 90 66 66 66 66 90 55 <80> 7f 4a 00 48 89 e5 5d 0f 95 c0 c3 0f 1f 40 00 66 2e 0f 1f 84 [ 383.853124] RIP [] pci_is_pcie+0x6/0x20 [ 383.853124] RSP Signed-off-by: Long Li --- drivers/pci/host/pci-hyperv.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index a8deeca..4a37598 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -348,6 +348,7 @@ enum hv_pcibus_state { hv_pcibus_init = 0, hv_pcibus_probed, hv_pcibus_installed, + hv_pcibus_removed, hv_pcibus_maximum }; @@ -1481,13 +1482,24 @@ static void pci_devices_present_work(struct work_struct *work) put_pcichild(hpdev, hv_pcidev_ref_initial); } - /* Tell the core to rescan bus because there may have been changes. */ - if (hbus->state == hv_pcibus_installed) { + switch (hbus->state) { + case hv_pcibus_installed: + /* +* Tell the core to rescan bus +* because there may have been changes. +*/ pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); pci_unlock_rescan_remove(); - } else { + break; + + case hv_pcibus_init: + case hv_pcibus_probed: survey_child_resources(hbus); + break; + + default: + break; } up(&hbus->enum_sem); @@ -2163,6 +2175,7 @@ static int hv_pci_probe(struct hv_device *hdev, hbus = kzalloc(sizeof(*hbus), GFP_KERNEL); if (!hbus) return -ENOMEM; + hbus->state = hv_pcibus_init; /* * The PCI bus "domain" is what is called "segment" in ACPI and @@ -2305,6 +2318,7 @@ static int hv_pci_remove(struct hv_device *hdev) pci_stop_root_bus(hbus->pci_bus); pci_remove_root_bus(hbus->pci_bus); pci_unlock_rescan_remove(); + hbus->state = hv_pcibus_removed; } ret = hv_send_resources_released(hdev); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/2 v2] pci-hyperv: properly handle pci bus remove
I have not been able to try out your second patch. So once that happens you can add my name. Cathy On 09/27/2016 07:54 PM, Long Li wrote: Thanks for pointing that out. If you don't mind, I will also add "Tested-by: Cathy Avery ". -Original Message- From: devel [mailto:driverdev-devel-boun...@linuxdriverproject.org] On Behalf Of Cathy Avery Sent: Friday, September 23, 2016 4:59 AM To: driverdev-devel@linuxdriverproject.org Subject: Re: [PATCH 1/2 v2] pci-hyperv: properly handle pci bus remove Hi, You seem to be missing the Reported-by tag. That's xiaof...@redhat.com. Cathy On 09/14/2016 10:10 PM, Long Li wrote: From: Long Li hv_pci_devices_present is called in hv_pci_remove when we remove a PCI device from host (e.g. by disabling SRIOV on a device). In hv_pci_remove, the bus is already removed before the call, so we don't need to rescan the bus in the workqueue scheduled from hv_pci_devices_present. By introducing status hv_pcibus_removed, we can avoid this situation. The patch fixes the following kernel panic. [ 383.853124] Workqueue: events pci_devices_present_work [pci_hyperv] [ 383.853124] task: 88007f5f8000 ti: 88007f60 task.ti: 88007f60 [ 383.853124] RIP: 0010:[] [] pci_is_pcie+0x6/0x20 [ 383.853124] RSP: 0018:88007f603d38 EFLAGS: 00010206 [ 383.853124] RAX: 88007f5f8000 RBX: 642f3d4854415056 RCX: 88007f603fd8 [ 383.853124] RDX: RSI: RDI: 642f3d4854415056 [ 383.853124] RBP: 88007f603d68 R08: 0246 R09: a045eb9e [ 383.853124] R10: 88007b419a80 R11: ea0001c0ef40 R12: 880003ee1c00 [ 383.853124] R13: 63702f30303a3137 R14: R15: 0246 [ 383.853124] FS: () GS:88007b40() knlGS: [ 383.853124] CS: 0010 DS: ES: CR0: 80050033 [ 383.853124] CR2: 7f68b3f52350 CR3: 03546000 CR4: 000406f0 [ 383.853124] DR0: DR1: DR2: [ 383.853124] DR3: DR6: 0ff0 DR7: 0400 [ 383.853124] Stack: [ 383.853124] 88007f603d68 8134db17 0008 880003ee1c00 [ 383.853124] 63702f30303a3137 880003d8edb8 88007f603da0 8134ee2d [ 383.853124] 880003d8ed00 88007f603dd8 880075fec320 880003d8edb8 [ 383.853124] Call Trace: [ 383.853124] [] ? pci_scan_slot+0x27/0x140 [ 383.853124] [] pci_scan_child_bus+0x3d/0x150 [ 383.853124] [] pci_devices_present_work+0x3ea/0x400 [pci_hyperv] [ 383.853124] [] process_one_work+0x17b/0x470 [ 383.853124] [] worker_thread+0x126/0x410 [ 383.853124] [] ? rescuer_thread+0x460/0x460 [ 383.853124] [] kthread+0xcf/0xe0 [ 383.853124] [] ? kthread_create_on_node+0x140/0x140 [ 383.853124] [] ret_from_fork+0x58/0x90 [ 383.853124] [] ? kthread_create_on_node+0x140/0x140 [ 383.853124] Code: 89 e5 5d 25 f0 00 00 00 c1 f8 04 c3 66 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 0f b6 47 4a 48 89 e5 5d c3 90 66 66 66 66 90 55 <80> 7f 4a 00 48 89 e5 5d 0f 95 c0 c3 0f 1f 40 00 66 2e 0f 1f 84 [ 383.853124] RIP [] pci_is_pcie+0x6/0x20 [ 383.853124] RSP Signed-off-by: Long Li --- drivers/pci/host/pci-hyperv.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index a8deeca..4a37598 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -348,6 +348,7 @@ enum hv_pcibus_state { hv_pcibus_init = 0, hv_pcibus_probed, hv_pcibus_installed, + hv_pcibus_removed, hv_pcibus_maximum }; @@ -1481,13 +1482,24 @@ static void pci_devices_present_work(struct work_struct *work) put_pcichild(hpdev, hv_pcidev_ref_initial); } - /* Tell the core to rescan bus because there may have been changes. */ - if (hbus->state == hv_pcibus_installed) { + switch (hbus->state) { + case hv_pcibus_installed: + /* +* Tell the core to rescan bus +* because there may have been changes. +*/ pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); pci_unlock_rescan_remove(); - } else { + break; + + case hv_pcibus_init: + case hv_pcibus_probed: survey_child_resources(hbus); + break; + + default: + break; } up(&hbus->enum_sem); @@ -2163,6 +2175,7 @@ static int hv_pci_probe(struct hv_device *hdev, hbus = kzalloc(sizeof(*hbus), GFP_KERNEL); if (!hbus) return -ENOMEM; + hbus->state = hv_pcibus_init; /* * The PCI bus "domain" is what is called "segment" in ACPI and @@ -2305,6 +2318,7 @@ static int hv_pci
[PATCH] [hv] storvsc: Payload buffer incorrectly sized for 32 bit kernels.
On a 32 bit kernel sizeof(void *) is not 64 bits as hv_mpb_array requires. Also the buffer needs to be cleared or the upper bytes could contain junk. Suggested-by: Vitaly Kuznets Signed-off-by: Cathy Avery --- drivers/scsi/storvsc_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 8ccfc9e..b4a8c9d 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1495,11 +1495,12 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) if (sg_count) { if (sg_count > MAX_PAGE_BUFFER_COUNT) { - payload_sz = (sg_count * sizeof(void *) + + payload_sz = (sg_count * sizeof(u64) + sizeof(struct vmbus_packet_mpb_array)); payload = kmalloc(payload_sz, GFP_ATOMIC); if (!payload) return SCSI_MLQUEUE_DEVICE_BUSY; + memset(payload, 0, payload_sz); } payload->range.len = length; -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2] [hv] storvsc: Payload buffer incorrectly sized for 32 bit kernels.
On a 32 bit kernel sizeof(void *) is not 64 bits as hv_mpb_array requires. Also the buffer needs to be cleared or the upper bytes will contain junk. Suggested-by: Vitaly Kuznetsov Signed-off-by: Cathy Avery ChangeLog: v1) Initial submission v2) Remove memset and replace kmalloc with kzalloc. --- drivers/scsi/storvsc_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 8ccfc9e..05526b7 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1495,9 +1495,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) if (sg_count) { if (sg_count > MAX_PAGE_BUFFER_COUNT) { - payload_sz = (sg_count * sizeof(void *) + + payload_sz = (sg_count * sizeof(u64) + sizeof(struct vmbus_packet_mpb_array)); - payload = kmalloc(payload_sz, GFP_ATOMIC); + payload = kzalloc(payload_sz, GFP_ATOMIC); if (!payload) return SCSI_MLQUEUE_DEVICE_BUSY; } -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] scsi: storvsc: Fix scsi_cmd error assignments in storvsc_handle_error
When an I/O is returned with an srb_status of SRB_STATUS_INVALID_LUN which has zero good_bytes it must be assigned an error. Otherwise the I/O will be continuously requeued and will cause a deadlock in the case where disks are being hot added and removed. sd_probe_async will wait forever for its I/O to complete while holding scsi_sd_probe_domain. Also returning the default error of DID_TARGET_FAILURE causes multipath to not retry the I/O resulting in applications receiving I/O errors before a failover can occur. Signed-off-by: Cathy Avery Signed-off-by: Long Li --- drivers/scsi/storvsc_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 1b06cf0..3b3d1d0 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -953,10 +953,11 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, case TEST_UNIT_READY: break; default: - set_host_byte(scmnd, DID_TARGET_FAILURE); + set_host_byte(scmnd, DID_ERROR); } break; case SRB_STATUS_INVALID_LUN: + set_host_byte(scmnd, DID_NO_CONNECT); do_work = true; process_err_fn = storvsc_remove_lun; break; -- 2.5.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] scsi: storvsc: missing error code in storvsc_probe()
On 01/16/2018 05:40 AM, Dan Carpenter wrote: We should set the error code if fc_remote_port_add() fails. Fixes: daf0cd445a21 ("scsi: storvsc: Add support for FC rport.") Signed-off-by: Dan Carpenter diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 3b3d1d050cac..40fc7a590e81 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1834,8 +1834,10 @@ static int storvsc_probe(struct hv_device *device, fc_host_node_name(host) = stor_device->node_name; fc_host_port_name(host) = stor_device->port_name; stor_device->rport = fc_remote_port_add(host, 0, &ids); - if (!stor_device->rport) + if (!stor_device->rport) { + ret = -ENOMEM; goto err_out4; + } } #endif return 0; Reviewed-by: Cathy Avery ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel