aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-12-05 20:06:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-12-05 20:06:31 -0500
commitcf76c364a1e1e5224af80edf70a1e3023e1fcf8c (patch)
tree5dd6c3467f2df2e164c303c0fb12fb038269b3f7
parent369af92ce47a04b2523ec4feea1febcacf8419b1 (diff)
parentc967590457cae5ba4f018704c341641bdcecfdcf (diff)
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Four obvious bug fixes. The vmw_pscsi is so old that it's amazing no-one noticed before now" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: storvsc: Fix a race in sub-channel creation that can cause panic scsi: vmw_pscsi: Rearrange code to avoid multiple calls to free_irq during unload scsi: libiscsi: Fix NULL pointer dereference in iscsi_eh_session_reset scsi: lpfc: fix block guard enablement on SLI3 adapters
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c1
-rw-r--r--drivers/scsi/storvsc_drv.c61
-rw-r--r--drivers/scsi/vmw_pvscsi.c4
5 files changed, 39 insertions, 37 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 93c66ebad907..f78d2e5c1471 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2416,8 +2416,8 @@ int iscsi_eh_session_reset(struct scsi_cmnd *sc)
2416failed: 2416failed:
2417 ISCSI_DBG_EH(session, 2417 ISCSI_DBG_EH(session,
2418 "failing session reset: Could not log back into " 2418 "failing session reset: Could not log back into "
2419 "%s, %s [age %d]\n", session->targetname, 2419 "%s [age %d]\n", session->targetname,
2420 conn->persistent_address, session->age); 2420 session->age);
2421 spin_unlock_bh(&session->frwd_lock); 2421 spin_unlock_bh(&session->frwd_lock);
2422 mutex_unlock(&session->eh_mutex); 2422 mutex_unlock(&session->eh_mutex);
2423 return FAILED; 2423 return FAILED;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 20fa6785a0e2..68d62d55a3a5 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -167,7 +167,11 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
167 sizeof(phba->wwpn)); 167 sizeof(phba->wwpn));
168 } 168 }
169 169
170 phba->sli3_options = 0x0; 170 /*
171 * Clear all option bits except LPFC_SLI3_BG_ENABLED,
172 * which was already set in lpfc_get_cfgparam()
173 */
174 phba->sli3_options &= (uint32_t)LPFC_SLI3_BG_ENABLED;
171 175
172 /* Setup and issue mailbox READ REV command */ 176 /* Setup and issue mailbox READ REV command */
173 lpfc_read_rev(phba, pmb); 177 lpfc_read_rev(phba, pmb);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 783a1540cfbe..b9e5cd79931a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4965,7 +4965,6 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode)
4965 phba->sli3_options &= ~(LPFC_SLI3_NPIV_ENABLED | 4965 phba->sli3_options &= ~(LPFC_SLI3_NPIV_ENABLED |
4966 LPFC_SLI3_HBQ_ENABLED | 4966 LPFC_SLI3_HBQ_ENABLED |
4967 LPFC_SLI3_CRP_ENABLED | 4967 LPFC_SLI3_CRP_ENABLED |
4968 LPFC_SLI3_BG_ENABLED |
4969 LPFC_SLI3_DSS_ENABLED); 4968 LPFC_SLI3_DSS_ENABLED);
4970 if (rc != MBX_SUCCESS) { 4969 if (rc != MBX_SUCCESS) {
4971 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 4970 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f03dc03a42c3..8f88348ebe42 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -446,7 +446,6 @@ struct storvsc_device {
446 446
447 bool destroy; 447 bool destroy;
448 bool drain_notify; 448 bool drain_notify;
449 bool open_sub_channel;
450 atomic_t num_outstanding_req; 449 atomic_t num_outstanding_req;
451 struct Scsi_Host *host; 450 struct Scsi_Host *host;
452 451
@@ -636,33 +635,38 @@ get_in_err:
636static void handle_sc_creation(struct vmbus_channel *new_sc) 635static void handle_sc_creation(struct vmbus_channel *new_sc)
637{ 636{
638 struct hv_device *device = new_sc->primary_channel->device_obj; 637 struct hv_device *device = new_sc->primary_channel->device_obj;
638 struct device *dev = &device->device;
639 struct storvsc_device *stor_device; 639 struct storvsc_device *stor_device;
640 struct vmstorage_channel_properties props; 640 struct vmstorage_channel_properties props;
641 int ret;
641 642
642 stor_device = get_out_stor_device(device); 643 stor_device = get_out_stor_device(device);
643 if (!stor_device) 644 if (!stor_device)
644 return; 645 return;
645 646
646 if (stor_device->open_sub_channel == false)
647 return;
648
649 memset(&props, 0, sizeof(struct vmstorage_channel_properties)); 647 memset(&props, 0, sizeof(struct vmstorage_channel_properties));
650 648
651 vmbus_open(new_sc, 649 ret = vmbus_open(new_sc,
652 storvsc_ringbuffer_size, 650 storvsc_ringbuffer_size,
653 storvsc_ringbuffer_size, 651 storvsc_ringbuffer_size,
654 (void *)&props, 652 (void *)&props,
655 sizeof(struct vmstorage_channel_properties), 653 sizeof(struct vmstorage_channel_properties),
656 storvsc_on_channel_callback, new_sc); 654 storvsc_on_channel_callback, new_sc);
657 655
658 if (new_sc->state == CHANNEL_OPENED_STATE) { 656 /* In case vmbus_open() fails, we don't use the sub-channel. */
659 stor_device->stor_chns[new_sc->target_cpu] = new_sc; 657 if (ret != 0) {
660 cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus); 658 dev_err(dev, "Failed to open sub-channel: err=%d\n", ret);
659 return;
661 } 660 }
661
662 /* Add the sub-channel to the array of available channels. */
663 stor_device->stor_chns[new_sc->target_cpu] = new_sc;
664 cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus);
662} 665}
663 666
664static void handle_multichannel_storage(struct hv_device *device, int max_chns) 667static void handle_multichannel_storage(struct hv_device *device, int max_chns)
665{ 668{
669 struct device *dev = &device->device;
666 struct storvsc_device *stor_device; 670 struct storvsc_device *stor_device;
667 int num_cpus = num_online_cpus(); 671 int num_cpus = num_online_cpus();
668 int num_sc; 672 int num_sc;
@@ -679,22 +683,12 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns)
679 request = &stor_device->init_request; 683 request = &stor_device->init_request;
680 vstor_packet = &request->vstor_packet; 684 vstor_packet = &request->vstor_packet;
681 685
682 stor_device->open_sub_channel = true;
683 /* 686 /*
684 * Establish a handler for dealing with subchannels. 687 * Establish a handler for dealing with subchannels.
685 */ 688 */
686 vmbus_set_sc_create_callback(device->channel, handle_sc_creation); 689 vmbus_set_sc_create_callback(device->channel, handle_sc_creation);
687 690
688 /* 691 /*
689 * Check to see if sub-channels have already been created. This
690 * can happen when this driver is re-loaded after unloading.
691 */
692
693 if (vmbus_are_subchannels_present(device->channel))
694 return;
695
696 stor_device->open_sub_channel = false;
697 /*
698 * Request the host to create sub-channels. 692 * Request the host to create sub-channels.
699 */ 693 */
700 memset(request, 0, sizeof(struct storvsc_cmd_request)); 694 memset(request, 0, sizeof(struct storvsc_cmd_request));
@@ -710,23 +704,29 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns)
710 VM_PKT_DATA_INBAND, 704 VM_PKT_DATA_INBAND,
711 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 705 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
712 706
713 if (ret != 0) 707 if (ret != 0) {
708 dev_err(dev, "Failed to create sub-channel: err=%d\n", ret);
714 return; 709 return;
710 }
715 711
716 t = wait_for_completion_timeout(&request->wait_event, 10*HZ); 712 t = wait_for_completion_timeout(&request->wait_event, 10*HZ);
717 if (t == 0) 713 if (t == 0) {
714 dev_err(dev, "Failed to create sub-channel: timed out\n");
718 return; 715 return;
716 }
719 717
720 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || 718 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
721 vstor_packet->status != 0) 719 vstor_packet->status != 0) {
720 dev_err(dev, "Failed to create sub-channel: op=%d, sts=%d\n",
721 vstor_packet->operation, vstor_packet->status);
722 return; 722 return;
723 }
723 724
724 /* 725 /*
725 * Now that we created the sub-channels, invoke the check; this 726 * We need to do nothing here, because vmbus_process_offer()
726 * may trigger the callback. 727 * invokes channel->sc_creation_callback, which will open and use
728 * the sub-channel(s).
727 */ 729 */
728 stor_device->open_sub_channel = true;
729 vmbus_are_subchannels_present(device->channel);
730} 730}
731 731
732static void cache_wwn(struct storvsc_device *stor_device, 732static void cache_wwn(struct storvsc_device *stor_device,
@@ -1794,7 +1794,6 @@ static int storvsc_probe(struct hv_device *device,
1794 } 1794 }
1795 1795
1796 stor_device->destroy = false; 1796 stor_device->destroy = false;
1797 stor_device->open_sub_channel = false;
1798 init_waitqueue_head(&stor_device->waiting_to_drain); 1797 init_waitqueue_head(&stor_device->waiting_to_drain);
1799 stor_device->device = device; 1798 stor_device->device = device;
1800 stor_device->host = host; 1799 stor_device->host = host;
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 6e491023fdd8..0d6b2a88fc8e 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)
1202 1202
1203static void pvscsi_release_resources(struct pvscsi_adapter *adapter) 1203static void pvscsi_release_resources(struct pvscsi_adapter *adapter)
1204{ 1204{
1205 pvscsi_shutdown_intr(adapter);
1206
1207 if (adapter->workqueue) 1205 if (adapter->workqueue)
1208 destroy_workqueue(adapter->workqueue); 1206 destroy_workqueue(adapter->workqueue);
1209 1207
@@ -1534,6 +1532,7 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1534out_reset_adapter: 1532out_reset_adapter:
1535 ll_adapter_reset(adapter); 1533 ll_adapter_reset(adapter);
1536out_release_resources: 1534out_release_resources:
1535 pvscsi_shutdown_intr(adapter);
1537 pvscsi_release_resources(adapter); 1536 pvscsi_release_resources(adapter);
1538 scsi_host_put(host); 1537 scsi_host_put(host);
1539out_disable_device: 1538out_disable_device:
@@ -1542,6 +1541,7 @@ out_disable_device:
1542 return error; 1541 return error;
1543 1542
1544out_release_resources_and_disable: 1543out_release_resources_and_disable:
1544 pvscsi_shutdown_intr(adapter);
1545 pvscsi_release_resources(adapter); 1545 pvscsi_release_resources(adapter);
1546 goto out_disable_device; 1546 goto out_disable_device;
1547} 1547}