Blob Blame History Raw
From: Erez Shitrit <erezsh@mellanox.com>
Date: Tue, 16 Oct 2012 10:53:26 +0200
Subject: ib/ipoib: Move QP to ERROR only when the QP is not at REST state
Patch-mainline: Not yet, expect submission soon
References: bnc#868011

ipoib_ib_dev_stop function moves the QP state to ERROR.
In case the QP is already in RESET state, moving the QP to ERROR state will fail.
Add a check in the code for QP current state before moving to ERROR
state.

Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Acked-by: John Jolly <jjolly@suse.de>
---
 drivers/infiniband/ulp/ipoib/ipoib_ib.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 6a7003d..9c5f390 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -817,6 +817,8 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ib_qp_attr qp_attr;
+	struct ib_qp_init_attr query_init_attr;
+	int ret;
 	unsigned long begin;
 	struct ipoib_tx_buf *tx_req;
 	int i;
@@ -830,9 +832,17 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
 	 * Move our QP to the error state and then reinitialize in
 	 * when all work requests have completed or have been flushed.
 	 */
-	qp_attr.qp_state = IB_QPS_ERR;
-	if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
-		ipoib_warn(priv, "Failed to modify QP to ERROR state\n");
+	ret = ib_query_qp(priv->qp, &qp_attr, IB_QP_STATE, &query_init_attr);
+
+	/* Cannot move to Error state if we still in RESET state.*/
+	if (!ret && qp_attr.qp_state != IB_QPS_RESET) {
+		qp_attr.qp_state = IB_QPS_ERR;
+		if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
+			ipoib_warn(priv, "Failed to modify QP to ERROR state\n");
+	} else
+		ipoib_dbg(priv, "ib_query_qp returned: %d,"
+				"qp state is %d, no need to move to ERROR.\n",
+			  ret, qp_attr.qp_state);
 
 	/* Wait for all sends and receives to complete */
 	begin = jiffies;
-- 
1.7.8.2