[ewg] [PATCH 2/5] RDMA/nes: fix for problem of RAW QP transision state to ERR.

miroslaw.walukiewicz at intel.com miroslaw.walukiewicz at intel.com
Thu Dec 9 08:01:26 PST 2010


The effect of going into ERR state is flushing all CQEs and return of
FLUSH_ERR status for each posted entry in both RQ and SQ.

Signed-off-by: Mirek Walukiewicz <miroslaw.walukiewicz at intel.com>
---

 .../fixes/nes_0052_ima_flush_qp_fix.patch          |   87 +++++++++++++++++++++++
 1 files changed, 87 insertions(+), 0 deletions(-)
 create mode 100644 kernel_patches/fixes/nes_0052_ima_flush_qp_fix.patch


diff --git a/kernel_patches/fixes/nes_0052_ima_flush_qp_fix.patch b/kernel_patches/fixes/nes_0052_ima_flush_qp_fix.patch
new file mode 100644
index 0000000..fd3ff5f
--- /dev/null
+++ b/kernel_patches/fixes/nes_0052_ima_flush_qp_fix.patch
@@ -0,0 +1,87 @@
+diff --git a/drivers/infiniband/hw/nes/nes_ud.c b/drivers/infiniband/hw/nes/nes_ud.c
+index 2cb6f0c..c784fad 100644
+--- a/drivers/infiniband/hw/nes/nes_ud.c
++++ b/drivers/infiniband/hw/nes/nes_ud.c
+@@ -892,6 +892,31 @@ static void nes_ud_destroy_nic(struct nes_ud_file *file)
+ 	return;
+ }
+ 
++int nes_ud_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
++		int attr_mask, struct ib_udata *udata)
++{
++	struct nes_qp *nesqp = to_nesqp(ibqp);
++	int ret = 0;
++
++	if (attr_mask & IB_QP_STATE) {
++		switch (attr->qp_state) {
++		case IB_QPS_ERR:
++			if (nesqp->rx_ud_wq)
++				nes_ud_destroy_nic(nesqp->rx_ud_wq);
++
++			if (nesqp->tx_ud_wq && (ret == 0))
++				nes_ud_destroy_nic(nesqp->tx_ud_wq);
++
++			nesqp->ibqp_state = IB_QPS_ERR;
++			break;
++
++		default:
++			break;
++		}
++	}
++	return ret;
++}
++
+ static void nes_ud_free_resources(struct nes_ud_file *file)
+ {
+ 	struct nes_device *nesdev = file->nesvnic->nesdev;
+@@ -952,9 +977,9 @@ static void nes_ud_free_resources(struct nes_ud_file *file)
+ 	  }
+ 	}
+ 
+-
+-
+-	nes_ud_destroy_nic(file);
++	if (file->qp_ptr)
++		if (file->qp_ptr->ibqp_state != IB_QPS_ERR)
++			nes_ud_destroy_nic(file);
+ 
+ 	if (file->queue_type == NES_UD_RECV_QUEUE) {
+ 		wqm_config0 = nes_read_indexed(nesdev, 0x5000);
+diff --git a/drivers/infiniband/hw/nes/nes_ud.h b/drivers/infiniband/hw/nes/nes_ud.h
+index 729b883..b28f6e2 100644
+--- a/drivers/infiniband/hw/nes/nes_ud.h
++++ b/drivers/infiniband/hw/nes/nes_ud.h
+@@ -80,5 +80,7 @@ int nes_ud_dereg_mr(u32 stag);
+ int nes_ud_subscribe_mcast(struct nes_ud_file *file, union ib_gid *gid);
+ int nes_ud_unsubscribe_mcast(struct nes_ud_file *file, union ib_gid *gid);
+ int nes_ud_cq_replace(struct nes_vnic *nesvnic, struct nes_cq *cq);
++int nes_ud_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
++		int attr_mask, struct ib_udata *udata);
+ 
+ #endif
+diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
+index edaa824..f009100 100644
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -1470,6 +1470,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
+ 		return ERR_PTR(-EFAULT);
+ 	}
+ 
++	nesqp->ibqp_state = IB_QPS_RTS;
+ 	/* create association between qp and tx/rx files
+ 	 it is used when CQ is replaced from user space */
+ 	nesqp->rx_ud_wq->qp_ptr = nesqp;
+@@ -3132,9 +3133,10 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 			nesqp->hwqp.qp_id, attr->qp_state, nesqp->ibqp_state,
+ 			nesqp->iwarp_state, atomic_read(&nesqp->refcount));
+ 
+-	if (ibqp->qp_type == IB_QPT_RAW_ETH)
+-		return 0;
+-
++	if (ibqp->qp_type == IB_QPT_RAW_ETH) {
++		ret = nes_ud_modify_qp(ibqp, attr, attr_mask, &udata);
++		return ret;
++	}
+ 	spin_lock_irqsave(&nesqp->lock, qplockflags);
+ 
+ 	nes_debug(NES_DBG_MOD_QP, "QP%u: hw_iwarp_state=0x%X, hw_tcp_state=0x%X,"





More information about the ewg mailing list