History

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley: "Four driver fixes and one core fix. The core fix closes a race window where we could kick off a second asynchronous scan because the test and set of the variable preventing it isn't atomic" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: hisi_sas: Stop using queue #0 always for v2 hw scsi: ibmvscsi: Fix potential race after loss of transport scsi: mptfusion: Fix null pointer dereferences in mptscsih_remove() scsi: qla2xxx: Return EBUSY on fcport deletion scsi: core: Don't start concurrent async scan on same host

Linus Torvalds committed 6 years ago

Commit 67ff3772 parents 5fc6b07 fab09aa5 files · +43 −21Browse files

Unified · Split

5 files
  1. drivers/message/fusion/mptscsih.c +8 −5
  2. drivers/scsi/hisi_sas/hisi_sas_main.c +1 −1
  3. drivers/scsi/ibmvscsi/ibmvscsi.c +26 −10
  4. drivers/scsi/qla2xxx/qla_nvme.c +4 −2
  5. drivers/scsi/scsi_scan.c +4 −3
drivers/message/fusion/mptscsih.c+8−5
@@ -1176,8 +1176,10 @@ mptscsih_remove(struct pci_dev *pdev) · 1175 unmodified lines
11761176 MPT_SCSI_HOST *hd;
11771177 int sz1;
11781178
1179− if((hd = shost_priv(host)) == NULL)
1180− return;
1179+ if (host == NULL)
1180+ hd = NULL;
1181+ else
1182+ hd = shost_priv(host);
11811183
11821184 mptscsih_shutdown(pdev);
11831185
@@ -1193,14 +1195,15 @@ mptscsih_remove(struct pci_dev *pdev) · 9 unmodified lines
11931195 "Free'd ScsiLookup (%d) memory\n",
11941196 ioc->name, sz1));
11951197
1196− kfree(hd->info_kbuf);
1198+ if (hd)
1199+ kfree(hd->info_kbuf);
11971200
11981201 /* NULL the Scsi_Host pointer
11991202 */
12001203 ioc->sh = NULL;
12011204
1202− scsi_host_put(host);
1203−
1205+ if (host)
1206+ scsi_host_put(host);
12041207 mpt_detach(pdev);
12051208
12061209 }
drivers/scsi/hisi_sas/hisi_sas_main.c+1−1
@@ -445,7 +445,7 @@ static int hisi_sas_task_prep(struct sas_task *task, · 444 unmodified lines
445445 }
446446 }
447447
448− if (scmd) {
448+ if (scmd && hisi_hba->shost->nr_hw_queues) {
449449 unsigned int dq_index;
450450 u32 blk_tag;
451451
drivers/scsi/ibmvscsi/ibmvscsi.c+26−10
@@ -806,6 +806,22 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) · 805 unmodified lines
806806 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
807807 }
808808
809+/**
810+ * ibmvscsi_set_request_limit - Set the adapter request_limit in response to
811+ * an adapter failure, reset, or SRP Login. Done under host lock to prevent
812+ * race with SCSI command submission.
813+ * @hostdata: adapter to adjust
814+ * @limit: new request limit
815+ */
816+static void ibmvscsi_set_request_limit(struct ibmvscsi_host_data *hostdata, int limit)
817+{
818+ unsigned long flags;
819+
820+ spin_lock_irqsave(hostdata->host->host_lock, flags);
821+ atomic_set(&hostdata->request_limit, limit);
822+ spin_unlock_irqrestore(hostdata->host->host_lock, flags);
823+}
824+
809825 /**
810826 * ibmvscsi_reset_host - Reset the connection to the server
811827 * @hostdata: struct ibmvscsi_host_data to reset
@@ -813,7 +829,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) · 1 unmodified line
813829 static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
814830 {
815831 scsi_block_requests(hostdata->host);
816− atomic_set(&hostdata->request_limit, 0);
832+ ibmvscsi_set_request_limit(hostdata, 0);
817833
818834 purge_requests(hostdata, DID_ERROR);
819835 hostdata->action = IBMVSCSI_HOST_ACTION_RESET;
@@ -1146,13 +1162,13 @@ static void login_rsp(struct srp_event_struct *evt_struct) · 326 unmodified lines
11461162 dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n",
11471163 evt_struct->xfer_iu->srp.login_rej.reason);
11481164 /* Login failed. */
1149− atomic_set(&hostdata->request_limit, -1);
1165+ ibmvscsi_set_request_limit(hostdata, -1);
11501166 return;
11511167 default:
11521168 dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n",
11531169 evt_struct->xfer_iu->srp.login_rsp.opcode);
11541170 /* Login failed. */
1155− atomic_set(&hostdata->request_limit, -1);
1171+ ibmvscsi_set_request_limit(hostdata, -1);
11561172 return;
11571173 }
11581174
@@ -1163,7 +1179,7 @@ static void login_rsp(struct srp_event_struct *evt_struct) · 4 unmodified lines
11631179 * This value is set rather than added to request_limit because
11641180 * request_limit could have been set to -1 by this client.
11651181 */
1166− atomic_set(&hostdata->request_limit,
1182+ ibmvscsi_set_request_limit(hostdata,
11671183 be32_to_cpu(evt_struct->xfer_iu->srp.login_rsp.req_lim_delta));
11681184
11691185 /* If we had any pending I/Os, kick them */
@@ -1195,13 +1211,13 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata) · 25 unmodified lines
11951211 login->req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
11961212 SRP_BUF_FORMAT_INDIRECT);
11971213
1198− spin_lock_irqsave(hostdata->host->host_lock, flags);
11991214 /* Start out with a request limit of 0, since this is negotiated in
12001215 * the login request we are just sending and login requests always
12011216 * get sent by the driver regardless of request_limit.
12021217 */
1203− atomic_set(&hostdata->request_limit, 0);
1218+ ibmvscsi_set_request_limit(hostdata, 0);
12041219
1220+ spin_lock_irqsave(hostdata->host->host_lock, flags);
12051221 rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2);
12061222 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
12071223 dev_info(hostdata->dev, "sent SRP login\n");
@@ -1781,7 +1797,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq, · 573 unmodified lines
17811797 return;
17821798 case VIOSRP_CRQ_XPORT_EVENT: /* Hypervisor telling us the connection is closed */
17831799 scsi_block_requests(hostdata->host);
1784− atomic_set(&hostdata->request_limit, 0);
1800+ ibmvscsi_set_request_limit(hostdata, 0);
17851801 if (crq->format == 0x06) {
17861802 /* We need to re-setup the interpartition connection */
17871803 dev_info(hostdata->dev, "Re-enabling adapter!\n");
@@ -2137,12 +2153,12 @@ static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata) · 349 unmodified lines
21372153 }
21382154
21392155 hostdata->action = IBMVSCSI_HOST_ACTION_NONE;
2156+ spin_unlock_irqrestore(hostdata->host->host_lock, flags);
21402157
21412158 if (rc) {
2142− atomic_set(&hostdata->request_limit, -1);
2159+ ibmvscsi_set_request_limit(hostdata, -1);
21432160 dev_err(hostdata->dev, "error after %s\n", action);
21442161 }
2145− spin_unlock_irqrestore(hostdata->host->host_lock, flags);
21462162
21472163 scsi_unblock_requests(hostdata->host);
21482164 }
@@ -2226,7 +2242,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) · 77 unmodified lines
22262242 init_waitqueue_head(&hostdata->work_wait_q);
22272243 hostdata->host = host;
22282244 hostdata->dev = dev;
2229− atomic_set(&hostdata->request_limit, -1);
2245+ ibmvscsi_set_request_limit(hostdata, -1);
22302246 hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT;
22312247
22322248 if (map_persist_bufs(hostdata)) {
drivers/scsi/qla2xxx/qla_nvme.c+4−2
@@ -554,10 +554,12 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, · 553 unmodified lines
554554
555555 fcport = qla_rport->fcport;
556556
557− if (!qpair || !fcport || (qpair && !qpair->fw_started) ||
558− (fcport && fcport->deleted))
557+ if (!qpair || !fcport)
559558 return -ENODEV;
560559
560+ if (!qpair->fw_started || fcport->deleted)
561+ return -EBUSY;
562+
561563 vha = fcport->vha;
562564
563565 if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
drivers/scsi/scsi_scan.c+4−3
@@ -1714,15 +1714,16 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) · 1713 unmodified lines
17141714 */
17151715 static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
17161716 {
1717− struct async_scan_data *data;
1717+ struct async_scan_data *data = NULL;
17181718 unsigned long flags;
17191719
17201720 if (strncmp(scsi_scan_type, "sync", 4) == 0)
17211721 return NULL;
17221722
1723+ mutex_lock(&shost->scan_mutex);
17231724 if (shost->async_scan) {
17241725 shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
1725− return NULL;
1726+ goto err;
17261727 }
17271728
17281729 data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -1733,7 +1734,6 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) · 4 unmodified lines
17331734 goto err;
17341735 init_completion(&data->prev_finished);
17351736
1736− mutex_lock(&shost->scan_mutex);
17371737 spin_lock_irqsave(shost->host_lock, flags);
17381738 shost->async_scan = 1;
17391739 spin_unlock_irqrestore(shost->host_lock, flags);
@@ -1748,6 +1748,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) · 8 unmodified lines
17481748 return data;
17491749
17501750 err:
1751+ mutex_unlock(&shost->scan_mutex);
17511752 kfree(data);
17521753 return NULL;
17531754 }