]> git.openfabrics.org - ~emulex/for-vlad/old/compat-rdma.git/commitdiff
iw_cxgb4: only log rx_data warnings if cpl status is non zero.
authorVipul Pandya <vipul@chelsio.com>
Thu, 8 Nov 2012 12:05:06 +0000 (04:05 -0800)
committerVipul Pandya <vipul@chelsio.com>
Thu, 8 Nov 2012 12:07:58 +0000 (04:07 -0800)
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 <vipul@chelsio.com>
linux-next-pending/0020-RDMA-cxgb4-abort-connections-when-moving-to-ERROR-st.patch [new file with mode: 0644]
linux-next-pending/0021-RDMA-cxgb4-Display-streaming-mode-error-only-if-dete.patch [new file with mode: 0644]
linux-next-pending/0022-RDMA-cxgb4-keep-qp-referenced-until-TID-released.patch [new file with mode: 0644]
linux-next-pending/0023-RDMA-cxgb4-Always-log-async-errors.patch [new file with mode: 0644]
linux-next-pending/0024-RDMA-cxgb4-only-log-rx_data-warnings-if-cpl-status-i.patch [new file with mode: 0644]

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 (file)
index 0000000..6cad6e9
--- /dev/null
@@ -0,0 +1,42 @@
+From 2c14e0b50d8f29f1186c5ab5c11837d1520df598 Mon Sep 17 00:00:00 2001
+From: Vipul Pandya <vipul@chelsio.com>
+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 <vipul@chelsio.com>
+---
+ 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 (file)
index 0000000..54ae6b7
--- /dev/null
@@ -0,0 +1,57 @@
+From 12bd8166547ede591410c6420d4665be6bedc8fd Mon Sep 17 00:00:00 2001
+From: Vipul Pandya <vipul@chelsio.com>
+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 <vipul@chelsio.com>
+---
+ 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 (file)
index 0000000..24942f0
--- /dev/null
@@ -0,0 +1,110 @@
+From f4d76e45f4b9438c8b8918f481ba617dfa9a37d3 Mon Sep 17 00:00:00 2001
+From: Vipul Pandya <vipul@chelsio.com>
+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 <vipul@chelsio.com>
+---
+ 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 (file)
index 0000000..c3e37a3
--- /dev/null
@@ -0,0 +1,53 @@
+From 06c3accf85a24991e09114d53fa84eaaa77890bf Mon Sep 17 00:00:00 2001
+From: Vipul Pandya <vipul@chelsio.com>
+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 <vipul@chelsio.com>
+---
+ 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 (file)
index 0000000..1cdcd34
--- /dev/null
@@ -0,0 +1,29 @@
+From 7064cb784a8515d6c65deec78eb6e839820434e8 Mon Sep 17 00:00:00 2001
+From: Vipul Pandya <vipul@chelsio.com>
+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 <vipul@chelsio.com>
+---
+ 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
+