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.

scsi: qla2xxx: Fix a race condition between aborting and completing a SCSI command

Instead of allocating a struct srb dynamically from inside .queuecommand(),
set qla2xxx_driver_template.cmd_size such that struct scsi_cmnd and struct
srb are contiguous. Do not call QLA_QPAIR_MARK_BUSY() /
QLA_QPAIR_MARK_NOT_BUSY() for SRBs associated with SCSI commands. That is
safe because scsi_remove_host() is called before queue pairs are deleted
and scsi_remove_host() waits for all outstanding SCSI commands to finish.

Cc: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Tested-by: Himanshu Madhani <hmadhani@marvell.com>
Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Bart Van Assche and committed by
Martin K. Petersen
85cffefa bdb61b9b

+8 -38
-1
drivers/scsi/qla2xxx/qla_def.h
··· 630 630 } srb_t; 631 631 632 632 #define GET_CMD_SP(sp) (sp->u.scmd.cmd) 633 - #define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd) 634 633 #define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx) 635 634 636 635 #define GET_CMD_SENSE_LEN(sp) \
+8 -37
drivers/scsi/qla2xxx/qla_os.c
··· 713 713 cmd->scsi_done(cmd); 714 714 if (comp) 715 715 complete(comp); 716 - qla2x00_rel_sp(sp); 717 716 } 718 717 719 718 void qla2xxx_qpair_sp_free_dma(srb_t *sp) ··· 813 814 cmd->scsi_done(cmd); 814 815 if (comp) 815 816 complete(comp); 816 - qla2xxx_rel_qpair_sp(sp->qpair, sp); 817 817 } 818 818 819 819 static int ··· 906 908 else 907 909 goto qc24_target_busy; 908 910 909 - sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 910 - if (!sp) 911 - goto qc24_host_busy; 911 + sp = scsi_cmd_priv(cmd); 912 + qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport); 912 913 913 914 sp->u.scmd.cmd = cmd; 914 915 sp->type = SRB_SCSI_CMD; ··· 927 930 928 931 qc24_host_busy_free_sp: 929 932 sp->free(sp); 930 - 931 - qc24_host_busy: 932 - return SCSI_MLQUEUE_HOST_BUSY; 933 933 934 934 qc24_target_busy: 935 935 return SCSI_MLQUEUE_TARGET_BUSY; ··· 988 994 else 989 995 goto qc24_target_busy; 990 996 991 - sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC); 992 - if (!sp) 993 - goto qc24_host_busy; 997 + sp = scsi_cmd_priv(cmd); 998 + qla2xxx_init_sp(sp, vha, qpair, fcport); 994 999 995 1000 sp->u.scmd.cmd = cmd; 996 1001 sp->type = SRB_SCSI_CMD; ··· 1012 1019 1013 1020 qc24_host_busy_free_sp: 1014 1021 sp->free(sp); 1015 - 1016 - qc24_host_busy: 1017 - return SCSI_MLQUEUE_HOST_BUSY; 1018 1022 1019 1023 qc24_target_busy: 1020 1024 return SCSI_MLQUEUE_TARGET_BUSY; ··· 1247 1257 int ret; 1248 1258 unsigned int id; 1249 1259 uint64_t lun; 1250 - unsigned long flags; 1251 1260 int rval; 1252 1261 struct qla_hw_data *ha = vha->hw; 1253 - struct qla_qpair *qpair; 1254 1262 1255 1263 if (qla2x00_isp_reg_stat(ha)) { 1256 1264 ql_log(ql_log_info, vha, 0x8042, ··· 1260 1272 if (ret != 0) 1261 1273 return ret; 1262 1274 1263 - sp = (srb_t *) CMD_SP(cmd); 1264 - if (!sp) 1265 - return SUCCESS; 1266 - 1267 - qpair = sp->qpair; 1268 - if (!qpair) 1269 - return SUCCESS; 1275 + sp = scsi_cmd_priv(cmd); 1270 1276 1271 1277 if (sp->fcport && sp->fcport->deleted) 1272 1278 return SUCCESS; 1273 1279 1274 - spin_lock_irqsave(qpair->qp_lock_ptr, flags); 1275 - if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) { 1276 - /* there's a chance an interrupt could clear 1277 - the ptr as part of done & free */ 1278 - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 1280 + /* Return if the command has already finished. */ 1281 + if (sp_get(sp)) 1279 1282 return SUCCESS; 1280 - } 1281 - 1282 - /* Get a reference to the sp and drop the lock. */ 1283 - if (sp_get(sp)){ 1284 - /* ref_count is already 0 */ 1285 - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 1286 - return SUCCESS; 1287 - } 1288 - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 1289 1283 1290 1284 id = cmd->device->id; 1291 1285 lun = cmd->device->lun; ··· 7129 7159 7130 7160 .supported_mode = MODE_INITIATOR, 7131 7161 .track_queue_depth = 1, 7162 + .cmd_size = sizeof(srb_t), 7132 7163 }; 7133 7164 7134 7165 static const struct pci_error_handlers qla2xxx_err_handler = {