mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 01:51:34 +00:00
scsi: lpfc: devloss timeout race condition caused null pointer reference
A race condition between the context of devloss timeout handler and I/O completion caused devloss timeout handler de-referencing pointer that had been released. Added the check in lpfc_sli_validate_fcp_iocb() on LPFC_IO_ON_TXCMPLQ to capture the race condition of I/O completion and devloss timeout handler attemption for aborting the I/O. Also, added check on lpfc_cmd->rdata pointer before de-referenceing lpfc_cmd->rdata->pnode. Also, added protection in lpfc_sli_abort_iocb() routine on driver performed FCP I/O FLUSHING already under way before proceeding to aborting I/Os. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
6871e8144f
commit
b0e830125b
@ -4538,6 +4538,11 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
|
||||
int err;
|
||||
|
||||
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
||||
|
||||
/* sanity check on references */
|
||||
if (unlikely(!rdata) || unlikely(!rport))
|
||||
goto out_fail_command;
|
||||
|
||||
err = fc_remote_port_chkready(rport);
|
||||
if (err) {
|
||||
cmnd->result = err;
|
||||
|
@ -11091,10 +11091,11 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
|
||||
struct lpfc_scsi_buf *lpfc_cmd;
|
||||
int rc = 1;
|
||||
|
||||
if (!(iocbq->iocb_flag & LPFC_IO_FCP))
|
||||
if (iocbq->vport != vport)
|
||||
return rc;
|
||||
|
||||
if (iocbq->vport != vport)
|
||||
if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
|
||||
!(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ))
|
||||
return rc;
|
||||
|
||||
lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
|
||||
@ -11104,13 +11105,13 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
|
||||
|
||||
switch (ctx_cmd) {
|
||||
case LPFC_CTX_LUN:
|
||||
if ((lpfc_cmd->rdata->pnode) &&
|
||||
if ((lpfc_cmd->rdata) && (lpfc_cmd->rdata->pnode) &&
|
||||
(lpfc_cmd->rdata->pnode->nlp_sid == tgt_id) &&
|
||||
(scsilun_to_int(&lpfc_cmd->fcp_cmnd->fcp_lun) == lun_id))
|
||||
rc = 0;
|
||||
break;
|
||||
case LPFC_CTX_TGT:
|
||||
if ((lpfc_cmd->rdata->pnode) &&
|
||||
if ((lpfc_cmd->rdata) && (lpfc_cmd->rdata->pnode) &&
|
||||
(lpfc_cmd->rdata->pnode->nlp_sid == tgt_id))
|
||||
rc = 0;
|
||||
break;
|
||||
@ -11225,6 +11226,10 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
|
||||
int errcnt = 0, ret_val = 0;
|
||||
int i;
|
||||
|
||||
/* all I/Os are in process of being flushed */
|
||||
if (phba->hba_flag & HBA_FCP_IOQ_FLUSH)
|
||||
return errcnt;
|
||||
|
||||
for (i = 1; i <= phba->sli.last_iotag; i++) {
|
||||
iocbq = phba->sli.iocbq_lookup[i];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user