From e953ceb2278e95aeed23dc1a9a1a6e4e665b0c23 Mon Sep 17 00:00:00 2001 From: Wei Lin Guay Date: Thu, 15 Sep 2016 10:44:26 +0200 Subject: [PATCH] sif: cq: do not return errors from poll_cq MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Orabug: 23321166 Remove returning errors from sif_poll_cq function. On the opposite, log the error and skip the CQEs and continue with the next CQE. Signed-off-by: Wei Lin Guay Reviewed-by: HÃ¥kon Bugge Reviewed-by: Knut Omang --- drivers/infiniband/hw/sif/sif_cq.c | 53 ++++++++++++---------------- drivers/infiniband/hw/sif/sif_defs.h | 1 + 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/infiniband/hw/sif/sif_cq.c b/drivers/infiniband/hw/sif/sif_cq.c index d49667330abe..a2cd5e559343 100644 --- a/drivers/infiniband/hw/sif/sif_cq.c +++ b/drivers/infiniband/hw/sif/sif_cq.c @@ -49,27 +49,27 @@ static inline int translate_wr_id( return -EFAULT; } if (!unlikely(wh->used)) { - if ((sq_seq_num == wh->sq_seq) || (cqe->status == PSIF_WC_STATUS_DUPL_COMPL_ERR)) { + if ((sq_seq_num == wh->sq_seq) || (cqe->status == PSIF_WC_STATUS_DUPL_COMPL_ERR)) sif_log(sdev, SIF_WCE, - "dupl cqe 0x%x for cq %d: got sq_seq 0x%x, last exp.0x%x, sts %d opc 0x%x", + "dupl cqe 0x%x for cq %d: got sq_seq 0x%x, last exp.0x%x, sts %d opc 0x%x", + cqe->seq_num, cq->index, sq_seq_num, wh->sq_seq, + cqe->status, cqe->opcode); + else + sif_log(sdev, SIF_INFO, + "unexp. cqe 0x%x for cq %d: got sq_seq 0x%x, last exp.0x%x, sts %d opc 0x%x", cqe->seq_num, cq->index, sq_seq_num, wh->sq_seq, cqe->status, cqe->opcode); - return -EIO; - } - sif_log(sdev, SIF_INFO, - "unexp. cqe 0x%x for cq %d: got sq_seq 0x%x, last exp.0x%x, sts %d opc 0x%x", - cqe->seq_num, cq->index, sq_seq_num, wh->sq_seq, - cqe->status, cqe->opcode); return -EFAULT; } if (unlikely(wh->sq_seq != sq_seq_num)) { - bool duplicate_comp_wrap_case = (wh->sq_seq - sq_seq_num == sq->entries); - int log_level = duplicate_comp_wrap_case ? SIF_WCE : SIF_INFO; + bool dup_case = (wh->sq_seq - sq_seq_num == sq->entries); + int log_level = dup_case ? SIF_WCE : SIF_INFO; sif_log(sdev, log_level, - "wrong cqe 0x%x for cq %d: got sq_seq 0x%x, expected 0x%x, sts %d opc 0x%x", - cqe->seq_num, cq->index, sq_seq_num, wh->sq_seq, cqe->status, cqe->opcode); - return duplicate_comp_wrap_case ? -EIO : -EFAULT; + "%s cqe 0x%x for cq %d: got sq_seq 0x%x, expected 0x%x, sts %d opc 0x%x", + dup_case ? "dupl" : "wrong", cqe->seq_num, cq->index, sq_seq_num, wh->sq_seq, + cqe->status, cqe->opcode); + return -EFAULT; } *wr_id = wh->wr_id; wh->used = false; @@ -407,7 +407,7 @@ static int handle_send_wc(struct sif_dev *sdev, struct sif_cq *cq, wc->wr_id = cqe->wc_id.rq_id; /* No more work, when QP is gone */ - return cqe->status == PSIF_WC_STATUS_DUPL_COMPL_ERR ? -EIO : 0; + return cqe->status == PSIF_WC_STATUS_GEN_TRANSL_COMPL_ERR ? -EFAULT : 0; } ret = translate_wr_id(&wc->wr_id, sdev, cq, sq, cqe, sq_seq_num, cqe->qp); @@ -754,8 +754,8 @@ int sif_fixup_cqes(struct sif_cq *cq, struct sif_sq *sq, struct sif_qp *qp) struct sif_cq_sw *cq_sw = get_sif_cq_sw(sdev, cq->index); u32 seqno; u32 polled_value; + int ret; int n = 0; - int ret = 0; unsigned long flags = 0; @@ -803,10 +803,8 @@ int sif_fixup_cqes(struct sif_cq *cq, struct sif_sq *sq, struct sif_qp *qp) /* If a send completion, handle the wr_id */ ret = translate_wr_id(&wr_id_host_order, sdev, cq, sq, &lcqe, lcqe.wc_id.sq_id.sq_seq_num, lcqe.qp); - if (ret == -EIO) - set_psif_cq_entry__status(cqe, PSIF_WC_STATUS_DUPL_COMPL_ERR); - else if (ret) - goto err; + if (ret < 0) + set_psif_cq_entry__status(cqe, PSIF_WC_STATUS_GEN_TRANSL_COMPL_ERR); set_psif_cq_entry__wc_id(cqe, wr_id_host_order); } @@ -818,7 +816,6 @@ int sif_fixup_cqes(struct sif_cq *cq, struct sif_sq *sq, struct sif_qp *qp) ret = n; -err: spin_unlock_irqrestore(&cq->lock, flags); @@ -843,7 +840,6 @@ int sif_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) u32 polled_value = 0; int npolled = 0; unsigned long flags = 0; - int ret = 0; /* TBD: Replace lock with atomic ops */ spin_lock_irqsave(&cq->lock, flags); @@ -866,17 +862,15 @@ int sif_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) break; if (likely(wc)) { - ret = handle_wc(sdev, cq, cqe, wc); - if (unlikely(ret == -EIO)) { - /* -EIO indicates that this is the duplicate - * FLUSH-IN-ERR completion generated by the HW. + if (unlikely(handle_wc(sdev, cq, cqe, wc) < 0)) { + /* poll_cq should not return < 0. Thus, ignore + * the CQE if it is duplicate, unexpected or wrong + * CQE. */ seqno = ++cq_sw->next_seq; npolled--; - ret = 0; continue; - } else if (ret < 0) - goto handle_failed; + } wc++; seqno = ++cq_sw->next_seq; } else /* peek_cq semantics */ @@ -893,7 +887,6 @@ int sif_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) } } -handle_failed: spin_unlock_irqrestore(&cq->lock, flags); if (npolled) @@ -902,7 +895,7 @@ handle_failed: else sif_log_rlim(sdev, SIF_POLL, "no completions polled - seq_no of next entry: %d", polled_value); - return !ret ? npolled : ret; + return npolled; } diff --git a/drivers/infiniband/hw/sif/sif_defs.h b/drivers/infiniband/hw/sif/sif_defs.h index e027cc6fde80..4ed1b076a4e2 100644 --- a/drivers/infiniband/hw/sif/sif_defs.h +++ b/drivers/infiniband/hw/sif/sif_defs.h @@ -38,6 +38,7 @@ struct xchar { #define GREATER_16(a, b) ((s16)((s16)(a) - (s16)(b)) > 0) #define LESS_OR_EQUAL_16(a, b) (!(GREATER_16((a), (b)))) #define PSIF_WC_STATUS_DUPL_COMPL_ERR (PSIF_WC_STATUS_FIELD_MAX - 1) +#define PSIF_WC_STATUS_GEN_TRANSL_COMPL_ERR (PSIF_WC_STATUS_FIELD_MAX - 2) #define XFILE struct xchar -- 2.50.1