Commit 5fc849d8 authored by Justin Tee's avatar Justin Tee Committed by Martin K. Petersen
Browse files

scsi: lpfc: Add new RCQE status for handling DMA failures



A new RCQE status value indicating DMA failure when transferring
asynchronously received data to an RQE is introduced.  Such errors are
unexpected and handlers are updated to log KERN_ERR and dump lpfc's debug
trace buffer to kmsg.

Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230417191558.83100-6-justintee8345@gmail.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 779d61df
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -536,9 +536,9 @@ struct sli4_wcqe_xri_aborted {
/* completion queue entry structure for rqe completion */
struct lpfc_rcqe {
	uint32_t word0;
#define lpfc_rcqe_bindex_SHIFT		16
#define lpfc_rcqe_bindex_MASK		0x0000FFF
#define lpfc_rcqe_bindex_WORD		word0
#define lpfc_rcqe_iv_SHIFT		31
#define lpfc_rcqe_iv_MASK		0x00000001
#define lpfc_rcqe_iv_WORD		word0
#define lpfc_rcqe_status_SHIFT		8
#define lpfc_rcqe_status_MASK		0x000000FF
#define lpfc_rcqe_status_WORD		word0
@@ -546,6 +546,7 @@ struct lpfc_rcqe {
#define FC_STATUS_RQ_BUF_LEN_EXCEEDED 	0x11 /* payload truncated */
#define FC_STATUS_INSUFF_BUF_NEED_BUF 	0x12 /* Insufficient buffers */
#define FC_STATUS_INSUFF_BUF_FRM_DISC 	0x13 /* Frame Discard */
#define FC_STATUS_RQ_DMA_FAILURE	0x14 /* DMA failure */
	uint32_t word1;
#define lpfc_rcqe_fcf_id_v1_SHIFT	0
#define lpfc_rcqe_fcf_id_v1_MASK	0x0000003F
+64 −0
Original line number Diff line number Diff line
@@ -14682,6 +14682,38 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
		spin_unlock_irqrestore(&phba->hbalock, iflags);
		workposted = true;
		break;
	case FC_STATUS_RQ_DMA_FAILURE:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2564 RQE DMA Error x%x, x%08x x%08x x%08x "
				"x%08x\n",
				status, rcqe->word0, rcqe->word1,
				rcqe->word2, rcqe->word3);
		/* If IV set, no further recovery */
		if (bf_get(lpfc_rcqe_iv, rcqe))
			break;
		/* recycle consumed resource */
		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++;
			spin_unlock_irqrestore(&phba->hbalock, iflags);
			break;
		}
		hrq->RQ_rcv_buf++;
		hrq->RQ_buf_posted--;
		spin_unlock_irqrestore(&phba->hbalock, iflags);
		lpfc_in_buf_free(phba, &dma_buf->dbuf);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2565 Unexpected RQE Status x%x, w0-3 x%08x "
				"x%08x x%08x x%08x\n",
				status, rcqe->word0, rcqe->word1,
				rcqe->word2, rcqe->word3);
		break;
	}
out:
	return workposted;
@@ -15203,6 +15235,38 @@ lpfc_sli4_nvmet_handle_rcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
		hrq->RQ_no_posted_buf++;
		/* Post more buffers if possible */
		break;
	case FC_STATUS_RQ_DMA_FAILURE:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2575 RQE DMA Error x%x, x%08x x%08x x%08x "
				"x%08x\n",
				status, rcqe->word0, rcqe->word1,
				rcqe->word2, rcqe->word3);
		/* If IV set, no further recovery */
		if (bf_get(lpfc_rcqe_iv, rcqe))
			break;
		/* recycle consumed resource */
		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++;
			spin_unlock_irqrestore(&phba->hbalock, iflags);
			break;
		}
		hrq->RQ_rcv_buf++;
		hrq->RQ_buf_posted--;
		spin_unlock_irqrestore(&phba->hbalock, iflags);
		lpfc_rq_buf_free(phba, &dma_buf->hbuf);
		break;
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
				"2576 Unexpected RQE Status x%x, w0-3 x%08x "
				"x%08x x%08x x%08x\n",
				status, rcqe->word0, rcqe->word1,
				rcqe->word2, rcqe->word3);
		break;
	}
out:
	return workposted;