From: Vipul Pandya Date: Thu, 8 Nov 2012 12:05:06 +0000 (-0800) Subject: iw_cxgb4: only log rx_data warnings if cpl status is non zero. X-Git-Tag: vofed-3.5-x~17 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=a8ed0b388164413ef7a8a8b024f283a0b566517c;p=~emulex%2Ffor-vlad%2Fcompat-rdma.git iw_cxgb4: only log rx_data warnings if cpl status is non zero. With newer firmware, we can get streaming data due to connection errors before the driver moves the QP out of RTS. This patch fixes bug 2401 in OFED bugzilla Signed-off-by: Vipul Pandya --- diff --git a/linux-next-pending/0020-RDMA-cxgb4-abort-connections-when-moving-to-ERROR-st.patch b/linux-next-pending/0020-RDMA-cxgb4-abort-connections-when-moving-to-ERROR-st.patch new file mode 100644 index 0000000..6cad6e9 --- /dev/null +++ b/linux-next-pending/0020-RDMA-cxgb4-abort-connections-when-moving-to-ERROR-st.patch @@ -0,0 +1,42 @@ +From 2c14e0b50d8f29f1186c5ab5c11837d1520df598 Mon Sep 17 00:00:00 2001 +From: Vipul Pandya +Date: Thu, 8 Nov 2012 12:57:40 +0530 +Subject: [PATCH 07/11] RDMA/cxgb4: abort connections when moving to ERROR state. + +If a FINI operation fails, then we need to ABORT instead +of CLOSE. Also, if we ABORT due to unexpected STREAMING +data, then wake up anybody blocked in FINI... + +Signed-off-by: Vipul Pandya +--- + drivers/infiniband/hw/cxgb4/cm.c | 1 + + drivers/infiniband/hw/cxgb4/qp.c | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 40f9b17..cb4c071 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -1439,6 +1439,7 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) + mutex_lock(&ep->com.mutex); + switch (ep->com.state) { + case ABORTING: ++ c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); + __state_set(&ep->com, DEAD); + release = 1; + break; +diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c +index 05bfe53..17ba4f8 100644 +--- a/drivers/infiniband/hw/cxgb4/qp.c ++++ b/drivers/infiniband/hw/cxgb4/qp.c +@@ -1383,6 +1383,7 @@ err: + qhp->ep = NULL; + set_state(qhp, C4IW_QP_STATE_ERROR); + free = 1; ++ abort = 1; + wake_up(&qhp->wait); + BUG_ON(!ep); + flush_qp(qhp); +-- +1.7.1 + diff --git a/linux-next-pending/0021-RDMA-cxgb4-Display-streaming-mode-error-only-if-dete.patch b/linux-next-pending/0021-RDMA-cxgb4-Display-streaming-mode-error-only-if-dete.patch new file mode 100644 index 0000000..54ae6b7 --- /dev/null +++ b/linux-next-pending/0021-RDMA-cxgb4-Display-streaming-mode-error-only-if-dete.patch @@ -0,0 +1,57 @@ +From 12bd8166547ede591410c6420d4665be6bedc8fd Mon Sep 17 00:00:00 2001 +From: Vipul Pandya +Date: Thu, 8 Nov 2012 13:08:45 +0530 +Subject: [PATCH 08/11] RDMA/cxgb4: Display streaming mode error only if detected in RTS. + +With later firmware, the chances of getting streaming mode data after +we exit RTS is likely, so we don't need to warn for it. The only real +case where we don't expect it is when the QP is in RTS. + +move QP to ERROR when streaming mode data received. + +Signed-off-by: Vipul Pandya +--- + drivers/infiniband/hw/cxgb4/cm.c | 26 ++++++++++++++------------ + 1 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index cb4c071..58896f0 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -1404,19 +1404,21 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) + ep->rcv_seq += dlen; + process_mpa_request(ep, skb); + break; ++ case FPDU_MODE: { ++ struct c4iw_qp_attributes attrs; ++ BUG_ON(!ep->com.qp); ++ if (ep->com.qp->attr.state == C4IW_QP_STATE_RTS) ++ pr_err("%s Unexpected streaming data." \ ++ " ep %p state %d tid %u status %d\n", ++ __func__, ep, state_read(&ep->com), ++ ep->hwtid, status); ++ attrs.next_state = C4IW_QP_STATE_ERROR; ++ c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, ++ C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); ++ c4iw_ep_disconnect (ep, 1, GFP_KERNEL); ++ break; ++ } + default: +- pr_err("%s Unexpected streaming data." \ +- " ep %p state %d tid %u status %d\n", +- __func__, ep, state_read(&ep->com), ep->hwtid, status); +- +- if (ep->com.qp) { +- struct c4iw_qp_attributes attrs; +- +- attrs.next_state = C4IW_QP_STATE_ERROR; +- c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, +- C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); +- } +- c4iw_ep_disconnect (ep, 1, GFP_KERNEL); + break; + } + return 0; +-- +1.7.1 + diff --git a/linux-next-pending/0022-RDMA-cxgb4-keep-qp-referenced-until-TID-released.patch b/linux-next-pending/0022-RDMA-cxgb4-keep-qp-referenced-until-TID-released.patch new file mode 100644 index 0000000..24942f0 --- /dev/null +++ b/linux-next-pending/0022-RDMA-cxgb4-keep-qp-referenced-until-TID-released.patch @@ -0,0 +1,110 @@ +From f4d76e45f4b9438c8b8918f481ba617dfa9a37d3 Mon Sep 17 00:00:00 2001 +From: Vipul Pandya +Date: Thu, 8 Nov 2012 13:57:21 +0530 +Subject: [PATCH 09/11] RDMA/cxgb4: keep qp referenced until TID released. + +The driver is currently releasing the last ref on the QP too early. +This can cause bus errors due to HW still fetching WRs from the hw queue. +The fix is to keep a qp ref until we release the HW TID. + +Signed-off-by: Vipul Pandya +--- + drivers/infiniband/hw/cxgb4/cm.c | 20 ++++++++++++++++---- + drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 + + 2 files changed, 17 insertions(+), 4 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 58896f0..dbe79cf 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -143,6 +143,18 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status); + static LIST_HEAD(timeout_list); + static spinlock_t timeout_lock; + ++static void deref_qp(struct c4iw_ep *ep) ++{ ++ c4iw_qp_rem_ref(&ep->com.qp->ibqp); ++ clear_bit(QP_REFERENCED, &ep->com.flags); ++} ++ ++static void ref_qp(struct c4iw_ep *ep) ++{ ++ set_bit(QP_REFERENCED, &ep->com.flags); ++ c4iw_qp_add_ref(&ep->com.qp->ibqp); ++} ++ + static void start_ep_timer(struct c4iw_ep *ep) + { + PDBG("%s ep %p\n", __func__, ep); +@@ -272,6 +284,8 @@ void _c4iw_free_ep(struct kref *kref) + + ep = container_of(kref, struct c4iw_ep, com.kref); + PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]); ++ if (test_bit(QP_REFERENCED, &ep->com.flags)) ++ deref_qp(ep); + if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) { + cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid); + dst_release(ep->dst); +@@ -864,7 +878,6 @@ static void close_complete_upcall(struct c4iw_ep *ep) + ep->com.cm_id->event_handler(ep->com.cm_id, &event); + ep->com.cm_id->rem_ref(ep->com.cm_id); + ep->com.cm_id = NULL; +- ep->com.qp = NULL; + set_bit(CLOSE_UPCALL, &ep->com.history); + } + } +@@ -907,7 +920,6 @@ static void peer_abort_upcall(struct c4iw_ep *ep) + ep->com.cm_id->event_handler(ep->com.cm_id, &event); + ep->com.cm_id->rem_ref(ep->com.cm_id); + ep->com.cm_id = NULL; +- ep->com.qp = NULL; + set_bit(ABORT_UPCALL, &ep->com.history); + } + } +@@ -947,7 +959,6 @@ static void connect_reply_upcall(struct c4iw_ep *ep, int status) + if (status < 0) { + ep->com.cm_id->rem_ref(ep->com.cm_id); + ep->com.cm_id = NULL; +- ep->com.qp = NULL; + } + } + +@@ -2435,6 +2446,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + cm_id->add_ref(cm_id); + ep->com.cm_id = cm_id; + ep->com.qp = qp; ++ ref_qp(ep); + + /* bind QP to EP and move to RTS */ + attrs.mpa_attr = ep->mpa_attr; +@@ -2465,7 +2477,6 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + return 0; + err1: + ep->com.cm_id = NULL; +- ep->com.qp = NULL; + cm_id->rem_ref(cm_id); + err: + c4iw_put_ep(&ep->com); +@@ -2506,6 +2517,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + ep->com.cm_id = cm_id; + ep->com.qp = get_qhp(dev, conn_param->qpn); + BUG_ON(!ep->com.qp); ++ ref_qp(ep); + PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn, + ep->com.qp, cm_id); + +diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +index 9c1644f..0aaaa0e 100644 +--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h ++++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +@@ -716,6 +716,7 @@ enum c4iw_ep_flags { + ABORT_REQ_IN_PROGRESS = 1, + RELEASE_RESOURCES = 2, + CLOSE_SENT = 3, ++ QP_REFERENCED = 5, + }; + + enum c4iw_ep_history { +-- +1.7.1 + diff --git a/linux-next-pending/0023-RDMA-cxgb4-Always-log-async-errors.patch b/linux-next-pending/0023-RDMA-cxgb4-Always-log-async-errors.patch new file mode 100644 index 0000000..c3e37a3 --- /dev/null +++ b/linux-next-pending/0023-RDMA-cxgb4-Always-log-async-errors.patch @@ -0,0 +1,53 @@ +From 06c3accf85a24991e09114d53fa84eaaa77890bf Mon Sep 17 00:00:00 2001 +From: Vipul Pandya +Date: Thu, 8 Nov 2012 14:37:26 +0530 +Subject: [PATCH 10/11] RDMA/cxgb4: Always log async errors. + +Log AEs even if the QP isn't in RTS. It is useful +information. + +Signed-off-by: Vipul Pandya +--- + drivers/infiniband/hw/cxgb4/cm.c | 6 +++--- + drivers/infiniband/hw/cxgb4/ev.c | 8 +++++--- + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index dbe79cf..6164268 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -1420,9 +1420,9 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) + BUG_ON(!ep->com.qp); + if (ep->com.qp->attr.state == C4IW_QP_STATE_RTS) + pr_err("%s Unexpected streaming data." \ +- " ep %p state %d tid %u status %d\n", +- __func__, ep, state_read(&ep->com), +- ep->hwtid, status); ++ " qpid %u ep %p state %d tid %u status %d\n", ++ __func__, ep->com.qp->wq.sq.qid, ep, ++ state_read(&ep->com), ep->hwtid, status); + attrs.next_state = C4IW_QP_STATE_ERROR; + c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, + C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); +diff --git a/drivers/infiniband/hw/cxgb4/ev.c b/drivers/infiniband/hw/cxgb4/ev.c +index cf2f6b4..6f158c3 100644 +--- a/drivers/infiniband/hw/cxgb4/ev.c ++++ b/drivers/infiniband/hw/cxgb4/ev.c +@@ -46,9 +46,11 @@ static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp, + + if ((qhp->attr.state == C4IW_QP_STATE_ERROR) || + (qhp->attr.state == C4IW_QP_STATE_TERMINATE)) { +- PDBG("%s AE received after RTS - " +- "qp state %d qpid 0x%x status 0x%x\n", __func__, +- qhp->attr.state, qhp->wq.sq.qid, CQE_STATUS(err_cqe)); ++ pr_err("%s AE after RTS - qpid 0x%x opcode %d status 0x%x " ++ "type %d wrid.hi 0x%x wrid.lo 0x%x\n", ++ __func__, CQE_QPID(err_cqe), CQE_OPCODE(err_cqe), ++ CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), ++ CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe)); + return; + } + +-- +1.7.1 + diff --git a/linux-next-pending/0024-RDMA-cxgb4-only-log-rx_data-warnings-if-cpl-status-i.patch b/linux-next-pending/0024-RDMA-cxgb4-only-log-rx_data-warnings-if-cpl-status-i.patch new file mode 100644 index 0000000..1cdcd34 --- /dev/null +++ b/linux-next-pending/0024-RDMA-cxgb4-only-log-rx_data-warnings-if-cpl-status-i.patch @@ -0,0 +1,29 @@ +From 7064cb784a8515d6c65deec78eb6e839820434e8 Mon Sep 17 00:00:00 2001 +From: Vipul Pandya +Date: Thu, 8 Nov 2012 14:39:46 +0530 +Subject: [PATCH] RDMA/cxgb4: only log rx_data warnings if cpl status is non zero. + +With newer firmware, we can get streaming data due to connection +errors before the driver moves the QP out of RTS. + +Signed-off-by: Vipul Pandya +--- + drivers/infiniband/hw/cxgb4/cm.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 6164268..7a216ed 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -1418,7 +1418,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) + case FPDU_MODE: { + struct c4iw_qp_attributes attrs; + BUG_ON(!ep->com.qp); +- if (ep->com.qp->attr.state == C4IW_QP_STATE_RTS) ++ if (status) + pr_err("%s Unexpected streaming data." \ + " qpid %u ep %p state %d tid %u status %d\n", + __func__, ep->com.qp->wq.sq.qid, ep, +-- +1.7.1 +