Skip to content

Commit 1fa8109

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Six fixes to four drivers and two core fixes. One core fix simply corrects a missed destroy_rcu_head() but the other is hopefully the end of an ongoing effort to make suspend/resume play nicely with scsi quiesce" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ibmvscsi: Fix empty event pool access during host removal scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton scsi: hisi_sas: Add softreset in hisi_sas_I_T_nexus_reset() scsi: qla2xxx: Fix NULL pointer crash due to stale CPUID scsi: qla2xxx: Fix FC-AL connection target discovery scsi: core: Avoid that a kernel warning appears during system resume scsi: core: Also call destroy_rcu_head() for passthrough requests scsi: iscsi: flush running unbind operations when removing a session
2 parents 1bdd3db + 7f5203c commit 1fa8109

File tree

6 files changed

+47
-8
lines changed

6 files changed

+47
-8
lines changed

drivers/scsi/hisi_sas/hisi_sas_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,12 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
18011801
}
18021802
hisi_sas_dereg_device(hisi_hba, device);
18031803

1804+
if (dev_is_sata(device)) {
1805+
rc = hisi_sas_softreset_ata_disk(device);
1806+
if (rc)
1807+
return TMF_RESP_FUNC_FAILED;
1808+
}
1809+
18041810
rc = hisi_sas_debug_I_T_nexus_reset(device);
18051811

18061812
if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV))

drivers/scsi/ibmvscsi/ibmvscsi.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static int client_reserve = 1;
9696
static char partition_name[96] = "UNKNOWN";
9797
static unsigned int partition_number = -1;
9898
static LIST_HEAD(ibmvscsi_head);
99+
static DEFINE_SPINLOCK(ibmvscsi_driver_lock);
99100

100101
static struct scsi_transport_template *ibmvscsi_transport_template;
101102

@@ -2270,7 +2271,9 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
22702271
}
22712272

22722273
dev_set_drvdata(&vdev->dev, hostdata);
2274+
spin_lock(&ibmvscsi_driver_lock);
22732275
list_add_tail(&hostdata->host_list, &ibmvscsi_head);
2276+
spin_unlock(&ibmvscsi_driver_lock);
22742277
return 0;
22752278

22762279
add_srp_port_failed:
@@ -2292,15 +2295,27 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
22922295
static int ibmvscsi_remove(struct vio_dev *vdev)
22932296
{
22942297
struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev);
2295-
list_del(&hostdata->host_list);
2296-
unmap_persist_bufs(hostdata);
2298+
unsigned long flags;
2299+
2300+
srp_remove_host(hostdata->host);
2301+
scsi_remove_host(hostdata->host);
2302+
2303+
purge_requests(hostdata, DID_ERROR);
2304+
2305+
spin_lock_irqsave(hostdata->host->host_lock, flags);
22972306
release_event_pool(&hostdata->pool, hostdata);
2307+
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
2308+
22982309
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata,
22992310
max_events);
23002311

23012312
kthread_stop(hostdata->work_thread);
2302-
srp_remove_host(hostdata->host);
2303-
scsi_remove_host(hostdata->host);
2313+
unmap_persist_bufs(hostdata);
2314+
2315+
spin_lock(&ibmvscsi_driver_lock);
2316+
list_del(&hostdata->host_list);
2317+
spin_unlock(&ibmvscsi_driver_lock);
2318+
23042319
scsi_host_put(hostdata->host);
23052320

23062321
return 0;

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4991,6 +4991,13 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
49914991
if ((domain & 0xf0) == 0xf0)
49924992
continue;
49934993

4994+
/* Bypass if not same domain and area of adapter. */
4995+
if (area && domain && ((area != vha->d_id.b.area) ||
4996+
(domain != vha->d_id.b.domain)) &&
4997+
(ha->current_topology == ISP_CFG_NL))
4998+
continue;
4999+
5000+
49945001
/* Bypass invalid local loop ID. */
49955002
if (loop_id > LAST_LOCAL_LOOP_ID)
49965003
continue;

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
15171517
goto eh_reset_failed;
15181518
}
15191519
err = 2;
1520-
if (do_reset(fcport, cmd->device->lun, blk_mq_rq_cpu(cmd->request) + 1)
1520+
if (do_reset(fcport, cmd->device->lun, 1)
15211521
!= QLA_SUCCESS) {
15221522
ql_log(ql_log_warn, vha, 0x800c,
15231523
"do_reset failed for cmd=%p.\n", cmd);

drivers/scsi/scsi_lib.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,16 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
585585
if (!blk_rq_is_scsi(req)) {
586586
WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
587587
cmd->flags &= ~SCMD_INITIALIZED;
588-
destroy_rcu_head(&cmd->rcu);
589588
}
590589

590+
/*
591+
* Calling rcu_barrier() is not necessary here because the
592+
* SCSI error handler guarantees that the function called by
593+
* call_rcu() has been called before scsi_end_request() is
594+
* called.
595+
*/
596+
destroy_rcu_head(&cmd->rcu);
597+
591598
/*
592599
* In the MQ case the command gets freed by __blk_mq_end_request,
593600
* so we have to do all cleanup that depends on it earlier.
@@ -2541,8 +2548,10 @@ void scsi_device_resume(struct scsi_device *sdev)
25412548
* device deleted during suspend)
25422549
*/
25432550
mutex_lock(&sdev->state_mutex);
2544-
sdev->quiesced_by = NULL;
2545-
blk_clear_pm_only(sdev->request_queue);
2551+
if (sdev->quiesced_by) {
2552+
sdev->quiesced_by = NULL;
2553+
blk_clear_pm_only(sdev->request_queue);
2554+
}
25462555
if (sdev->sdev_state == SDEV_QUIESCE)
25472556
scsi_device_set_state(sdev, SDEV_RUNNING);
25482557
mutex_unlock(&sdev->state_mutex);

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,8 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
22002200
scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE);
22012201
/* flush running scans then delete devices */
22022202
flush_work(&session->scan_work);
2203+
/* flush running unbind operations */
2204+
flush_work(&session->unbind_work);
22032205
__iscsi_unbind_session(&session->unbind_work);
22042206

22052207
/* hw iscsi may not have removed all connections from session */

0 commit comments

Comments
 (0)