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
1176 MPT_SCSI_HOST *hd;1176 MPT_SCSI_HOST *hd;
1177 int sz1;1177 int sz1;
1178 1178
1179 if((hd = shost_priv(host)) == NULL)1179 if (host == NULL)
1180 return;1180 hd = NULL;
1181 else
1182 hd = shost_priv(host);
1181 1183
1182 mptscsih_shutdown(pdev);1184 mptscsih_shutdown(pdev);
1183 1185
@@ -1193,14 +1195,15 @@ mptscsih_remove(struct pci_dev *pdev) · 9 unmodified lines
1193 "Free'd ScsiLookup (%d) memory\n",1195 "Free'd ScsiLookup (%d) memory\n",
1194 ioc->name, sz1));1196 ioc->name, sz1));
1195 1197
1196 kfree(hd->info_kbuf);1198 if (hd)
1199 kfree(hd->info_kbuf);
1197 1200
1198 /* NULL the Scsi_Host pointer1201 /* NULL the Scsi_Host pointer
1199 */1202 */
1200 ioc->sh = NULL;1203 ioc->sh = NULL;
1201 1204
1202 scsi_host_put(host);1205 if (host)
1203 1206 scsi_host_put(host);
1204 mpt_detach(pdev);1207 mpt_detach(pdev);
1205 1208
1206}1209}
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
445 }445 }
446 }446 }
447 447
448 if (scmd) {448 if (scmd && hisi_hba->shost->nr_hw_queues) {
449 unsigned int dq_index;449 unsigned int dq_index;
450 u32 blk_tag;450 u32 blk_tag;
451 451
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
806 spin_unlock_irqrestore(hostdata->host->host_lock, flags);806 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
807}807}
808 808
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 */
816static 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
809/**825/**
810 * ibmvscsi_reset_host - Reset the connection to the server826 * ibmvscsi_reset_host - Reset the connection to the server
811 * @hostdata: struct ibmvscsi_host_data to reset827 * @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
813static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)829static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
814{830{
815 scsi_block_requests(hostdata->host);831 scsi_block_requests(hostdata->host);
816 atomic_set(&hostdata->request_limit, 0);832 ibmvscsi_set_request_limit(hostdata, 0);
817 833
818 purge_requests(hostdata, DID_ERROR);834 purge_requests(hostdata, DID_ERROR);
819 hostdata->action = IBMVSCSI_HOST_ACTION_RESET;835 hostdata->action = IBMVSCSI_HOST_ACTION_RESET;
@@ -1146,13 +1162,13 @@ static void login_rsp(struct srp_event_struct *evt_struct) · 326 unmodified lines
1146 dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n",1162 dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n",
1147 evt_struct->xfer_iu->srp.login_rej.reason);1163 evt_struct->xfer_iu->srp.login_rej.reason);
1148 /* Login failed. */1164 /* Login failed. */
1149 atomic_set(&hostdata->request_limit, -1);1165 ibmvscsi_set_request_limit(hostdata, -1);
1150 return;1166 return;
1151 default:1167 default:
1152 dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n",1168 dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n",
1153 evt_struct->xfer_iu->srp.login_rsp.opcode);1169 evt_struct->xfer_iu->srp.login_rsp.opcode);
1154 /* Login failed. */1170 /* Login failed. */
1155 atomic_set(&hostdata->request_limit, -1);1171 ibmvscsi_set_request_limit(hostdata, -1);
1156 return;1172 return;
1157 }1173 }
1158 1174
@@ -1163,7 +1179,7 @@ static void login_rsp(struct srp_event_struct *evt_struct) · 4 unmodified lines
1163 * This value is set rather than added to request_limit because1179 * This value is set rather than added to request_limit because
1164 * request_limit could have been set to -1 by this client.1180 * request_limit could have been set to -1 by this client.
1165 */1181 */
1166 atomic_set(&hostdata->request_limit,1182 ibmvscsi_set_request_limit(hostdata,
1167 be32_to_cpu(evt_struct->xfer_iu->srp.login_rsp.req_lim_delta));1183 be32_to_cpu(evt_struct->xfer_iu->srp.login_rsp.req_lim_delta));
1168 1184
1169 /* If we had any pending I/Os, kick them */1185 /* 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
1195 login->req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |1211 login->req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
1196 SRP_BUF_FORMAT_INDIRECT);1212 SRP_BUF_FORMAT_INDIRECT);
1197 1213
1198 spin_lock_irqsave(hostdata->host->host_lock, flags);
1199 /* Start out with a request limit of 0, since this is negotiated in1214 /* Start out with a request limit of 0, since this is negotiated in
1200 * the login request we are just sending and login requests always1215 * the login request we are just sending and login requests always
1201 * get sent by the driver regardless of request_limit.1216 * get sent by the driver regardless of request_limit.
1202 */1217 */
1203 atomic_set(&hostdata->request_limit, 0);1218 ibmvscsi_set_request_limit(hostdata, 0);
1204 1219
1220 spin_lock_irqsave(hostdata->host->host_lock, flags);
1205 rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2);1221 rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2);
1206 spin_unlock_irqrestore(hostdata->host->host_lock, flags);1222 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
1207 dev_info(hostdata->dev, "sent SRP login\n");1223 dev_info(hostdata->dev, "sent SRP login\n");
@@ -1781,7 +1797,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq, · 573 unmodified lines
1781 return;1797 return;
1782 case VIOSRP_CRQ_XPORT_EVENT: /* Hypervisor telling us the connection is closed */1798 case VIOSRP_CRQ_XPORT_EVENT: /* Hypervisor telling us the connection is closed */
1783 scsi_block_requests(hostdata->host);1799 scsi_block_requests(hostdata->host);
1784 atomic_set(&hostdata->request_limit, 0);1800 ibmvscsi_set_request_limit(hostdata, 0);
1785 if (crq->format == 0x06) {1801 if (crq->format == 0x06) {
1786 /* We need to re-setup the interpartition connection */1802 /* We need to re-setup the interpartition connection */
1787 dev_info(hostdata->dev, "Re-enabling adapter!\n");1803 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
2137 }2153 }
2138 2154
2139 hostdata->action = IBMVSCSI_HOST_ACTION_NONE;2155 hostdata->action = IBMVSCSI_HOST_ACTION_NONE;
2156 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
2140 2157
2141 if (rc) {2158 if (rc) {
2142 atomic_set(&hostdata->request_limit, -1);2159 ibmvscsi_set_request_limit(hostdata, -1);
2143 dev_err(hostdata->dev, "error after %s\n", action);2160 dev_err(hostdata->dev, "error after %s\n", action);
2144 }2161 }
2145 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
2146 2162
2147 scsi_unblock_requests(hostdata->host);2163 scsi_unblock_requests(hostdata->host);
2148}2164}
@@ -2226,7 +2242,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) · 77 unmodified lines
2226 init_waitqueue_head(&hostdata->work_wait_q);2242 init_waitqueue_head(&hostdata->work_wait_q);
2227 hostdata->host = host;2243 hostdata->host = host;
2228 hostdata->dev = dev;2244 hostdata->dev = dev;
2229 atomic_set(&hostdata->request_limit, -1);2245 ibmvscsi_set_request_limit(hostdata, -1);
2230 hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT;2246 hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT;
2231 2247
2232 if (map_persist_bufs(hostdata)) {2248 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
554 554
555 fcport = qla_rport->fcport;555 fcport = qla_rport->fcport;
556 556
557 if (!qpair || !fcport || (qpair && !qpair->fw_started) ||557 if (!qpair || !fcport)
558 (fcport && fcport->deleted))
559 return -ENODEV;558 return -ENODEV;
560 559
560 if (!qpair->fw_started || fcport->deleted)
561 return -EBUSY;
562
561 vha = fcport->vha;563 vha = fcport->vha;
562 564
563 if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))565 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
1714 */1714 */
1715static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)1715static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
1716{1716{
1717 struct async_scan_data *data;1717 struct async_scan_data *data = NULL;
1718 unsigned long flags;1718 unsigned long flags;
1719 1719
1720 if (strncmp(scsi_scan_type, "sync", 4) == 0)1720 if (strncmp(scsi_scan_type, "sync", 4) == 0)
1721 return NULL;1721 return NULL;
1722 1722
1723 mutex_lock(&shost->scan_mutex);
1723 if (shost->async_scan) {1724 if (shost->async_scan) {
1724 shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);1725 shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
1725 return NULL;1726 goto err;
1726 }1727 }
1727 1728
1728 data = kmalloc(sizeof(*data), GFP_KERNEL);1729 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
1733 goto err;1734 goto err;
1734 init_completion(&data->prev_finished);1735 init_completion(&data->prev_finished);
1735 1736
1736 mutex_lock(&shost->scan_mutex);
1737 spin_lock_irqsave(shost->host_lock, flags);1737 spin_lock_irqsave(shost->host_lock, flags);
1738 shost->async_scan = 1;1738 shost->async_scan = 1;
1739 spin_unlock_irqrestore(shost->host_lock, flags);1739 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
1748 return data;1748 return data;
1749 1749
1750 err:1750 err:
1751 mutex_unlock(&shost->scan_mutex);
1751 kfree(data);1752 kfree(data);
1752 return NULL;1753 return NULL;
1753}1754}