diff options
author | James Smart <james.smart@emulex.com> | 2012-05-09 21:17:07 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-05-17 05:57:29 -0400 |
commit | 4f2e66c6d225a14fcf77d826fe71f6137cb27352 (patch) | |
tree | b6235968d1a223d83e750d41aab8100f912a68ea /drivers/scsi/lpfc/lpfc_sli.c | |
parent | a7dd9c0f44966b4328b52c5e32f8c3345e3482e5 (diff) |
[SCSI] lpfc 8.3.31: Fixed system panic due to midlayer abort and driver complete race on SCSI cmd
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 57eaaa51e1d6..7c4067913c29 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -502,7 +502,7 @@ lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
502 | * allocation is successful, it returns pointer to the newly | 502 | * allocation is successful, it returns pointer to the newly |
503 | * allocated iocb object else it returns NULL. | 503 | * allocated iocb object else it returns NULL. |
504 | **/ | 504 | **/ |
505 | static struct lpfc_iocbq * | 505 | struct lpfc_iocbq * |
506 | __lpfc_sli_get_iocbq(struct lpfc_hba *phba) | 506 | __lpfc_sli_get_iocbq(struct lpfc_hba *phba) |
507 | { | 507 | { |
508 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; | 508 | struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list; |
@@ -1259,7 +1259,7 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
1259 | struct lpfc_iocbq *piocb) | 1259 | struct lpfc_iocbq *piocb) |
1260 | { | 1260 | { |
1261 | list_add_tail(&piocb->list, &pring->txcmplq); | 1261 | list_add_tail(&piocb->list, &pring->txcmplq); |
1262 | piocb->iocb_flag |= LPFC_IO_ON_Q; | 1262 | piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ; |
1263 | pring->txcmplq_cnt++; | 1263 | pring->txcmplq_cnt++; |
1264 | if (pring->txcmplq_cnt > pring->txcmplq_max) | 1264 | if (pring->txcmplq_cnt > pring->txcmplq_max) |
1265 | pring->txcmplq_max = pring->txcmplq_cnt; | 1265 | pring->txcmplq_max = pring->txcmplq_cnt; |
@@ -2558,9 +2558,9 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba, | |||
2558 | if (iotag != 0 && iotag <= phba->sli.last_iotag) { | 2558 | if (iotag != 0 && iotag <= phba->sli.last_iotag) { |
2559 | cmd_iocb = phba->sli.iocbq_lookup[iotag]; | 2559 | cmd_iocb = phba->sli.iocbq_lookup[iotag]; |
2560 | list_del_init(&cmd_iocb->list); | 2560 | list_del_init(&cmd_iocb->list); |
2561 | if (cmd_iocb->iocb_flag & LPFC_IO_ON_Q) { | 2561 | if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) { |
2562 | pring->txcmplq_cnt--; | 2562 | pring->txcmplq_cnt--; |
2563 | cmd_iocb->iocb_flag &= ~LPFC_IO_ON_Q; | 2563 | cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; |
2564 | } | 2564 | } |
2565 | return cmd_iocb; | 2565 | return cmd_iocb; |
2566 | } | 2566 | } |
@@ -2593,14 +2593,14 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba, | |||
2593 | 2593 | ||
2594 | if (iotag != 0 && iotag <= phba->sli.last_iotag) { | 2594 | if (iotag != 0 && iotag <= phba->sli.last_iotag) { |
2595 | cmd_iocb = phba->sli.iocbq_lookup[iotag]; | 2595 | cmd_iocb = phba->sli.iocbq_lookup[iotag]; |
2596 | list_del_init(&cmd_iocb->list); | 2596 | if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) { |
2597 | if (cmd_iocb->iocb_flag & LPFC_IO_ON_Q) { | 2597 | /* remove from txcmpl queue list */ |
2598 | cmd_iocb->iocb_flag &= ~LPFC_IO_ON_Q; | 2598 | list_del_init(&cmd_iocb->list); |
2599 | cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; | ||
2599 | pring->txcmplq_cnt--; | 2600 | pring->txcmplq_cnt--; |
2601 | return cmd_iocb; | ||
2600 | } | 2602 | } |
2601 | return cmd_iocb; | ||
2602 | } | 2603 | } |
2603 | |||
2604 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 2604 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
2605 | "0372 iotag x%x is out off range: max iotag (x%x)\n", | 2605 | "0372 iotag x%x is out off range: max iotag (x%x)\n", |
2606 | iotag, phba->sli.last_iotag); | 2606 | iotag, phba->sli.last_iotag); |
@@ -3468,6 +3468,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) | |||
3468 | /* Retrieve everything on the txcmplq */ | 3468 | /* Retrieve everything on the txcmplq */ |
3469 | list_splice_init(&pring->txcmplq, &txcmplq); | 3469 | list_splice_init(&pring->txcmplq, &txcmplq); |
3470 | pring->txcmplq_cnt = 0; | 3470 | pring->txcmplq_cnt = 0; |
3471 | |||
3472 | /* Indicate the I/O queues are flushed */ | ||
3473 | phba->hba_flag |= HBA_FCP_IOQ_FLUSH; | ||
3471 | spin_unlock_irq(&phba->hbalock); | 3474 | spin_unlock_irq(&phba->hbalock); |
3472 | 3475 | ||
3473 | /* Flush the txq */ | 3476 | /* Flush the txq */ |
@@ -6069,6 +6072,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6069 | else | 6072 | else |
6070 | phba->hba_flag &= ~HBA_FIP_SUPPORT; | 6073 | phba->hba_flag &= ~HBA_FIP_SUPPORT; |
6071 | 6074 | ||
6075 | phba->hba_flag &= ~HBA_FCP_IOQ_FLUSH; | ||
6076 | |||
6072 | if (phba->sli_rev != LPFC_SLI_REV4) { | 6077 | if (phba->sli_rev != LPFC_SLI_REV4) { |
6073 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 6078 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
6074 | "0376 READ_REV Error. SLI Level %d " | 6079 | "0376 READ_REV Error. SLI Level %d " |