@@ -806,6 +806,8 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
unsigned long begin;
struct ipoib_tx_buf *tx_req;
int i;
+ struct ib_qp_init_attr qp_init_attr;
+ int err;
if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
napi_disable(&priv->napi);
@@ -813,12 +815,24 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
ipoib_cm_dev_stop(dev);
/*
+ * if we fail to query the QP we continue as if it was in
+ * a state different than RESET so we carry any cleanup possible
+ */
+ err = ib_query_qp(priv->qp, &qp_attr, IB_QP_CUR_STATE, &qp_init_attr);
+ if (err) {
+ ipoib_warn(priv, "Failed to query QP state, err %d\n", err);
+ qp_attr.cur_qp_state = IB_QPS_INIT;
+ }
+
+ /*
* 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");
+ if (qp_attr.cur_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");
+ }
/* Wait for all sends and receives to complete */
begin = jiffies;