Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull SCSI fixes from James Bottomley:
"Seven fixes, all in drivers (qla2xxx, mkt3sas, qedi, target,
ibmvscsi).

The most serious are the target pscsi oom and the qla2xxx revert which
can otherwise cause a use after free"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: target: pscsi: Clean up after failure in pscsi_map_sg()
scsi: target: pscsi: Avoid OOM in pscsi_map_sg()
scsi: mpt3sas: Fix error return code of mpt3sas_base_attach()
scsi: qedi: Fix error return code of qedi_alloc_global_queues()
scsi: Revert "qla2xxx: Make sure that aborted commands are freed"
scsi: ibmvfc: Make ibmvfc_wait_for_ops() MQ aware
scsi: ibmvfc: Fix potential race in ibmvfc_wait_for_ops()

+74 -28
+54 -13
drivers/scsi/ibmvscsi/ibmvfc.c
··· 2372 2372 } 2373 2373 2374 2374 /** 2375 + * ibmvfc_event_is_free - Check if event is free or not 2376 + * @evt: ibmvfc event struct 2377 + * 2378 + * Returns: 2379 + * true / false 2380 + **/ 2381 + static bool ibmvfc_event_is_free(struct ibmvfc_event *evt) 2382 + { 2383 + struct ibmvfc_event *loop_evt; 2384 + 2385 + list_for_each_entry(loop_evt, &evt->queue->free, queue_list) 2386 + if (loop_evt == evt) 2387 + return true; 2388 + 2389 + return false; 2390 + } 2391 + 2392 + /** 2375 2393 * ibmvfc_wait_for_ops - Wait for ops to complete 2376 2394 * @vhost: ibmvfc host struct 2377 2395 * @device: device to match (starget or sdev) ··· 2403 2385 { 2404 2386 struct ibmvfc_event *evt; 2405 2387 DECLARE_COMPLETION_ONSTACK(comp); 2406 - int wait; 2388 + int wait, i, q_index, q_size; 2407 2389 unsigned long flags; 2408 2390 signed long timeout = IBMVFC_ABORT_WAIT_TIMEOUT * HZ; 2391 + struct ibmvfc_queue *queues; 2409 2392 2410 2393 ENTER; 2394 + if (vhost->mq_enabled && vhost->using_channels) { 2395 + queues = vhost->scsi_scrqs.scrqs; 2396 + q_size = vhost->scsi_scrqs.active_queues; 2397 + } else { 2398 + queues = &vhost->crq; 2399 + q_size = 1; 2400 + } 2401 + 2411 2402 do { 2412 2403 wait = 0; 2413 - spin_lock_irqsave(&vhost->crq.l_lock, flags); 2414 - list_for_each_entry(evt, &vhost->crq.sent, queue_list) { 2415 - if (match(evt, device)) { 2416 - evt->eh_comp = &comp; 2417 - wait++; 2404 + spin_lock_irqsave(vhost->host->host_lock, flags); 2405 + for (q_index = 0; q_index < q_size; q_index++) { 2406 + spin_lock(&queues[q_index].l_lock); 2407 + for (i = 0; i < queues[q_index].evt_pool.size; i++) { 2408 + evt = &queues[q_index].evt_pool.events[i]; 2409 + if (!ibmvfc_event_is_free(evt)) { 2410 + if (match(evt, device)) { 2411 + evt->eh_comp = &comp; 2412 + wait++; 2413 + } 2414 + } 2418 2415 } 2416 + spin_unlock(&queues[q_index].l_lock); 2419 2417 } 2420 - spin_unlock_irqrestore(&vhost->crq.l_lock, flags); 2418 + spin_unlock_irqrestore(vhost->host->host_lock, flags); 2421 2419 2422 2420 if (wait) { 2423 2421 timeout = wait_for_completion_timeout(&comp, timeout); 2424 2422 2425 2423 if (!timeout) { 2426 2424 wait = 0; 2427 - spin_lock_irqsave(&vhost->crq.l_lock, flags); 2428 - list_for_each_entry(evt, &vhost->crq.sent, queue_list) { 2429 - if (match(evt, device)) { 2430 - evt->eh_comp = NULL; 2431 - wait++; 2425 + spin_lock_irqsave(vhost->host->host_lock, flags); 2426 + for (q_index = 0; q_index < q_size; q_index++) { 2427 + spin_lock(&queues[q_index].l_lock); 2428 + for (i = 0; i < queues[q_index].evt_pool.size; i++) { 2429 + evt = &queues[q_index].evt_pool.events[i]; 2430 + if (!ibmvfc_event_is_free(evt)) { 2431 + if (match(evt, device)) { 2432 + evt->eh_comp = NULL; 2433 + wait++; 2434 + } 2435 + } 2432 2436 } 2437 + spin_unlock(&queues[q_index].l_lock); 2433 2438 } 2434 - spin_unlock_irqrestore(&vhost->crq.l_lock, flags); 2439 + spin_unlock_irqrestore(vhost->host->host_lock, flags); 2435 2440 if (wait) 2436 2441 dev_err(vhost->dev, "Timed out waiting for aborted commands\n"); 2437 2442 LEAVE;
+6 -2
drivers/scsi/mpt3sas/mpt3sas_base.c
··· 7806 7806 ioc->pend_os_device_add_sz++; 7807 7807 ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, 7808 7808 GFP_KERNEL); 7809 - if (!ioc->pend_os_device_add) 7809 + if (!ioc->pend_os_device_add) { 7810 + r = -ENOMEM; 7810 7811 goto out_free_resources; 7812 + } 7811 7813 7812 7814 ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz; 7813 7815 ioc->device_remove_in_progress = 7814 7816 kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL); 7815 - if (!ioc->device_remove_in_progress) 7817 + if (!ioc->device_remove_in_progress) { 7818 + r = -ENOMEM; 7816 7819 goto out_free_resources; 7820 + } 7817 7821 7818 7822 ioc->fwfault_debug = mpt3sas_fwfault_debug; 7819 7823
+1
drivers/scsi/qedi/qedi_main.c
··· 1675 1675 if (!qedi->global_queues[i]) { 1676 1676 QEDI_ERR(&qedi->dbg_ctx, 1677 1677 "Unable to allocation global queue %d.\n", i); 1678 + status = -ENOMEM; 1678 1679 goto mem_alloc_failure; 1679 1680 } 1680 1681
+5 -8
drivers/scsi/qla2xxx/qla_target.c
··· 3222 3222 if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || 3223 3223 (cmd->sess && cmd->sess->deleted)) { 3224 3224 cmd->state = QLA_TGT_STATE_PROCESSED; 3225 - res = 0; 3226 - goto free; 3225 + return 0; 3227 3226 } 3228 3227 3229 3228 ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018, ··· 3233 3234 3234 3235 res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, 3235 3236 &full_req_cnt); 3236 - if (unlikely(res != 0)) 3237 - goto free; 3237 + if (unlikely(res != 0)) { 3238 + return res; 3239 + } 3238 3240 3239 3241 spin_lock_irqsave(qpair->qp_lock_ptr, flags); 3240 3242 ··· 3255 3255 vha->flags.online, qla2x00_reset_active(vha), 3256 3256 cmd->reset_count, qpair->chip_reset); 3257 3257 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3258 - res = 0; 3259 - goto free; 3258 + return 0; 3260 3259 } 3261 3260 3262 3261 /* Does F/W have an IOCBs for this request */ ··· 3358 3359 qlt_unmap_sg(vha, cmd); 3359 3360 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3360 3361 3361 - free: 3362 - vha->hw->tgt.tgt_ops->free_cmd(cmd); 3363 3362 return res; 3364 3363 } 3365 3364 EXPORT_SYMBOL(qlt_xmit_response);
-4
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 644 644 { 645 645 struct qla_tgt_cmd *cmd = container_of(se_cmd, 646 646 struct qla_tgt_cmd, se_cmd); 647 - struct scsi_qla_host *vha = cmd->vha; 648 647 649 648 if (cmd->aborted) { 650 649 /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task ··· 656 657 cmd->se_cmd.transport_state, 657 658 cmd->se_cmd.t_state, 658 659 cmd->se_cmd.se_cmd_flags); 659 - vha->hw->tgt.tgt_ops->free_cmd(cmd); 660 660 return 0; 661 661 } 662 662 ··· 683 685 { 684 686 struct qla_tgt_cmd *cmd = container_of(se_cmd, 685 687 struct qla_tgt_cmd, se_cmd); 686 - struct scsi_qla_host *vha = cmd->vha; 687 688 int xmit_type = QLA_TGT_XMIT_STATUS; 688 689 689 690 if (cmd->aborted) { ··· 696 699 cmd, kref_read(&cmd->se_cmd.cmd_kref), 697 700 cmd->se_cmd.transport_state, cmd->se_cmd.t_state, 698 701 cmd->se_cmd.se_cmd_flags); 699 - vha->hw->tgt.tgt_ops->free_cmd(cmd); 700 702 return 0; 701 703 } 702 704 cmd->bufflen = se_cmd->data_length;
+8 -1
drivers/target/target_core_pscsi.c
··· 882 882 if (!bio) { 883 883 new_bio: 884 884 nr_vecs = bio_max_segs(nr_pages); 885 - nr_pages -= nr_vecs; 886 885 /* 887 886 * Calls bio_kmalloc() and sets bio->bi_end_io() 888 887 */ ··· 938 939 939 940 return 0; 940 941 fail: 942 + if (bio) 943 + bio_put(bio); 944 + while (req->bio) { 945 + bio = req->bio; 946 + req->bio = bio->bi_next; 947 + bio_put(bio); 948 + } 949 + req->biotail = NULL; 941 950 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 942 951 } 943 952