diff options
author | James Smart <jsmart2021@gmail.com> | 2017-12-09 04:18:04 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-12-21 05:11:45 +0300 |
commit | cbc5de1b8a0f67beeafa9e474803709368f55175 (patch) | |
tree | c439e81828b6a9381a14086d4e63c1a9e810784d /drivers/scsi/lpfc/lpfc_sli.c | |
parent | cf1a1d3e2d88af49472014db0c82779b4fe85455 (diff) | |
download | linux-cbc5de1b8a0f67beeafa9e474803709368f55175.tar.xz |
scsi: lpfc: Fix -EOVERFLOW behavior for NVMET and defer_rcv
The driver is all set to handle the defer_rcv api for the nvmet_fc
transport, yet didn't properly recognize the return status when the
defer_rcv occurred. The driver treated it simply as an error and aborted
the io. Several residual issues occurred at that point.
Finish the defer_rcv support: recognize the return status when the io
request is being handled in a deferred style. This stops the rogue
aborts; Replenish the async cmd rcv buffer in the deferred receive if
needed.
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1d489b89954e..5f5528a12308 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -475,28 +475,30 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, struct lpfc_rqe *temp_hrqe; struct lpfc_rqe *temp_drqe; struct lpfc_register doorbell; - int put_index; + int hq_put_index; + int dq_put_index; /* sanity check on queue memory */ if (unlikely(!hq) || unlikely(!dq)) return -ENOMEM; - put_index = hq->host_index; - temp_hrqe = hq->qe[put_index].rqe; - temp_drqe = dq->qe[dq->host_index].rqe; + hq_put_index = hq->host_index; + dq_put_index = dq->host_index; + temp_hrqe = hq->qe[hq_put_index].rqe; + temp_drqe = dq->qe[dq_put_index].rqe; if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ) return -EINVAL; - if (put_index != dq->host_index) + if (hq_put_index != dq_put_index) return -EINVAL; /* If the host has not yet processed the next entry then we are done */ - if (((put_index + 1) % hq->entry_count) == hq->hba_index) + if (((hq_put_index + 1) % hq->entry_count) == hq->hba_index) return -EBUSY; lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size); lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size); /* Update the host index to point to the next slot */ - hq->host_index = ((put_index + 1) % hq->entry_count); - dq->host_index = ((dq->host_index + 1) % dq->entry_count); + hq->host_index = ((hq_put_index + 1) % hq->entry_count); + dq->host_index = ((dq_put_index + 1) % dq->entry_count); hq->RQ_buf_posted++; /* Ring The Header Receive Queue Doorbell */ @@ -517,7 +519,7 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, } writel(doorbell.word0, hq->db_regaddr); } - return put_index; + return hq_put_index; } /** @@ -12887,8 +12889,8 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe) lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "2537 Receive Frame Truncated!!\n"); case FC_STATUS_RQ_SUCCESS: - lpfc_sli4_rq_release(hrq, drq); spin_lock_irqsave(&phba->hbalock, iflags); + lpfc_sli4_rq_release(hrq, drq); dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list); if (!dma_buf) { hrq->RQ_no_buf_found++; @@ -13290,8 +13292,8 @@ lpfc_sli4_nvmet_handle_rcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, "6126 Receive Frame Truncated!!\n"); /* Drop thru */ case FC_STATUS_RQ_SUCCESS: - lpfc_sli4_rq_release(hrq, drq); spin_lock_irqsave(&phba->hbalock, iflags); + lpfc_sli4_rq_release(hrq, drq); dma_buf = lpfc_sli_rqbuf_get(phba, hrq); if (!dma_buf) { hrq->RQ_no_buf_found++; |