[openib-general] [PATCH 4/4] [RFC] Use ib_modify_qp_is_ok in ehca

Roland Dreier rolandd at cisco.com
Fri Feb 10 16:51:58 PST 2006


Convert ehca to use ib_modify_qp_is_ok() instead of its own QP
transition table.  Compile tested only because of lack of hardware.
(Well, actually IBM has kindly supplied a couple of systems, but the
rack isn't quite set up).

In any case, IBM people: please make sure I didn't break anything, and
if the patch is OK, please apply.

--- infiniband/hw/ehca/ehca_qp.c	(revision 5364)
+++ infiniband/hw/ehca/ehca_qp.c	(working copy)
@@ -178,223 +178,13 @@ static inline enum ehca_qp_type ib2ehcaq
 	}
 }
 
-/** @brief struct describes a state transition via modify qp
- */
-struct ehca_modqp_statetrans {
-	enum ib_qp_statetrans statetrans;
-	int req_attr[QPT_MAX];
-	int opt_attr[QPT_MAX];
-};
-
-/** @brief state transition table used by modify qp
- * the order is defined by transitions listed in enum ib_qp_statetrans
- */
-static const struct ehca_modqp_statetrans modqp_statetrans_table[IB_QPST_MAX] = {
-	[IB_QPST_ANY2RESET] = {.statetrans = IB_QPST_ANY2RESET},
-	[IB_QPST_ANY2ERR] = {.statetrans = IB_QPST_ANY2ERR},
-	[IB_QPST_RESET2INIT] = {
-		.statetrans = IB_QPST_RESET2INIT,
-		.req_attr = {
-			[QPT_RC] = (IB_QP_STATE |
-				    IB_QP_PKEY_INDEX |
-				    IB_QP_PORT |
-				    IB_QP_ACCESS_FLAGS),
-			[QPT_UC] = (IB_QP_STATE |
-				    IB_QP_PKEY_INDEX |
-				    IB_QP_PORT |
-				    IB_QP_ACCESS_FLAGS),
-			[QPT_UD] = (IB_QP_STATE |
-				    IB_QP_PKEY_INDEX |
-				    IB_QP_PORT |
-				    IB_QP_QKEY),
-			[QPT_SQP] = (IB_QP_STATE |
-				     IB_QP_PKEY_INDEX |
-				     IB_QP_PORT |
-				     IB_QP_QKEY)
-		}
-	},
-	[IB_QPST_INIT2RTR] = {
-		.statetrans = IB_QPST_INIT2RTR,
-		.req_attr = {
-			[QPT_RC] = (IB_QP_STATE |
-				    IB_QP_RQ_PSN |
-				    IB_QP_PATH_MTU |
-				    IB_QP_MAX_DEST_RD_ATOMIC |
-				    IB_QP_DEST_QPN |
-				    IB_QP_AV |
-				    IB_QP_MIN_RNR_TIMER),
-			[QPT_UC] = (IB_QP_STATE |
-				    IB_QP_RQ_PSN |
-				    IB_QP_PATH_MTU |
-				    IB_QP_DEST_QPN |
-				    IB_QP_AV),
-			[QPT_UD] = (IB_QP_STATE),
-			[QPT_SQP] = (IB_QP_STATE)
-		},
-		.opt_attr = {
-			[QPT_RC] = (IB_QP_ALT_PATH |
-				    IB_QP_ACCESS_FLAGS |
-				    IB_QP_PKEY_INDEX),
-			[QPT_UC] = (IB_QP_ALT_PATH |
-				    IB_QP_ACCESS_FLAGS |
-				    IB_QP_PKEY_INDEX),
-			[QPT_UD] = (IB_QP_PKEY_INDEX |
-				    IB_QP_QKEY),
-			[QPT_SQP] = (IB_QP_PKEY_INDEX |
-				     IB_QP_QKEY)
-		}
-	},
-	[IB_QPST_INIT2INIT] = {
-		.statetrans = IB_QPST_INIT2INIT,
-		.opt_attr = {
-			[QPT_RC] = (IB_QP_PKEY_INDEX |
-				    IB_QP_ACCESS_FLAGS |
-				    IB_QP_PORT),
-			[QPT_UC] = (IB_QP_PKEY_INDEX |
-				    IB_QP_ACCESS_FLAGS |
-				    IB_QP_PORT),
-			[QPT_UD] = (IB_QP_QKEY |
-				    IB_QP_PKEY_INDEX |
-				    IB_QP_PORT),
-			[QPT_SQP] = (IB_QP_QKEY |
-				     IB_QP_PKEY_INDEX |
-				     IB_QP_PORT)
-		}
-	},
-	[IB_QPST_RTR2RTS] = {
-		.statetrans = IB_QPST_RTR2RTS,
-		.req_attr = {
-			[QPT_RC] = (IB_QP_STATE |
-				    IB_QP_SQ_PSN |
-				    IB_QP_MAX_QP_RD_ATOMIC |
-				    IB_QP_RNR_RETRY |
-				    IB_QP_TIMEOUT |
-				    IB_QP_RETRY_CNT),
-			[QPT_UC] = (IB_QP_STATE |
-				    IB_QP_SQ_PSN),
-			[QPT_UD] = (IB_QP_STATE |
-				    IB_QP_SQ_PSN),
-			[QPT_SQP] = (IB_QP_STATE |
-				     IB_QP_SQ_PSN)
-		},
-		.opt_attr = {
-			[QPT_RC] = (IB_QP_PATH_MIG_STATE |
-				    IB_QP_ALT_PATH |
-				    IB_QP_MIN_RNR_TIMER |
-				    IB_QP_ACCESS_FLAGS |
-				    IB_QP_CUR_STATE),
-			[QPT_UC] = (IB_QP_PATH_MIG_STATE |
-				    IB_QP_ALT_PATH |
-				    IB_QP_ACCESS_FLAGS |
-				    IB_QP_CUR_STATE),
-			[QPT_UD] = (IB_QP_QKEY |
-				    IB_QP_CUR_STATE),
-			[QPT_SQP] = (IB_QP_QKEY |
-				     IB_QP_CUR_STATE)
-		}
-	},
-	[IB_QPST_RTS2SQD] = {
-		.statetrans = IB_QPST_RTS2SQD,
-		.req_attr = {
-			[QPT_RC] = (IB_QP_STATE),
-			[QPT_UC] = (IB_QP_STATE),
-			[QPT_UD] = (IB_QP_STATE),
-			[QPT_SQP] = (IB_QP_STATE)
-		},
-	},
-	[IB_QPST_RTS2RTS] = {
-		.statetrans = IB_QPST_RTS2RTS,
-		.opt_attr = {
-			[QPT_RC] = (IB_QP_PATH_MIG_STATE |
-				    IB_QP_ALT_PATH |
-				    IB_QP_MIN_RNR_TIMER |
-				    IB_QP_ACCESS_FLAGS),
-			[QPT_UC] = (IB_QP_PATH_MIG_STATE |
-				    IB_QP_ALT_PATH |
-				    IB_QP_ACCESS_FLAGS),
-			[QPT_UD] = (IB_QP_QKEY |
-				    IB_QP_CUR_STATE),
-			[QPT_SQP] = (IB_QP_QKEY |
-				     IB_QP_CUR_STATE)
-		}
-	},
-	[IB_QPST_SQD2RTS] = {
-		.statetrans = IB_QPST_SQD2RTS,
-		.req_attr = {
-			[QPT_RC] = (IB_QP_STATE),
-			[QPT_UC] = (IB_QP_STATE),
-			[QPT_UD] = (IB_QP_STATE),
-			[QPT_SQP] = (IB_QP_STATE)
-		},
-		.opt_attr = {
-			[QPT_RC]  = (IB_QP_ALT_PATH |
-				     IB_QP_ACCESS_FLAGS |
-				     IB_QP_MIN_RNR_TIMER |
-				     IB_QP_PATH_MIG_STATE |
-				     IB_QP_CUR_STATE),
-			[QPT_UC]  = (IB_QP_ALT_PATH |
-				     IB_QP_ACCESS_FLAGS |
-				     IB_QP_PATH_MIG_STATE |
-				     IB_QP_CUR_STATE),
-			[QPT_UD]  = (IB_QP_QKEY |
-				     IB_QP_CUR_STATE),
-			[QPT_SQP]  = (IB_QP_QKEY |
-				      IB_QP_CUR_STATE)
-		}
-	},
-	[IB_QPST_SQE2RTS] = {
-		.statetrans = IB_QPST_SQE2RTS,
-		.req_attr = {
-			[QPT_RC] = (IB_QP_STATE),
-			[QPT_UC] = (IB_QP_STATE),
-			[QPT_UD] = (IB_QP_STATE),
-			[QPT_SQP] = (IB_QP_STATE)
-		},
-		.opt_attr = {
-			[QPT_UC] = (IB_QP_CUR_STATE |
-				    IB_QP_ACCESS_FLAGS),
-			[QPT_UD] = (IB_QP_QKEY |
-				    IB_QP_CUR_STATE),
-			[QPT_SQP] = (IB_QP_QKEY |
-				     IB_QP_CUR_STATE)
-		}
-	},
-	[IB_QPST_SQD2SQD] = {
-		.statetrans = IB_QPST_SQD2SQD,
-		.opt_attr = {
-			[QPT_RC]  = (IB_QP_ALT_PATH |
-				     IB_QP_ACCESS_FLAGS |
-				     IB_QP_MIN_RNR_TIMER |
-				     IB_QP_PATH_MIG_STATE |
-				     IB_QP_AV |
-				     IB_QP_MAX_QP_RD_ATOMIC |
-				     IB_QP_MAX_DEST_RD_ATOMIC |
-				     IB_QP_CUR_STATE |
-				     IB_QP_PKEY_INDEX |
-				     IB_QP_TIMEOUT |
-				     IB_QP_RETRY_CNT |
-				     IB_QP_RNR_RETRY),
-			[QPT_UC]  = (IB_QP_ALT_PATH |
-				     IB_QP_ACCESS_FLAGS |
-				     IB_QP_PATH_MIG_STATE |
-				     IB_QP_AV |
-				     IB_QP_CUR_STATE |
-				     IB_QP_PKEY_INDEX),
-			[QPT_UD]  = (IB_QP_QKEY |
-				     IB_QP_PKEY_INDEX),
-			[QPT_SQP]  = (IB_QP_QKEY |
-				      IB_QP_PKEY_INDEX)
-		}
-	},
-};
-
 /** @brief validates  qp state transition  from/to state
  * output: req and opt attr masks in statetrans
  * returns: 0 if transition  valid
  *         -EINVAL if not
  */
-static inline int get_modqp_statetrans(int ib_fromstate, int ib_tostate,
-				       struct ehca_modqp_statetrans *statetrans)
+static inline enum ib_qp_statetrans
+get_modqp_statetrans(int ib_fromstate, int ib_tostate)
 {
 	int index = -EINVAL;
 	switch (ib_tostate) {
@@ -439,9 +229,6 @@ static inline int get_modqp_statetrans(i
 		return -EINVAL;
 	}
 
-	if (index >= 0)
-		*statetrans = modqp_statetrans_table[index];
-
 	return index;
 }
 
@@ -1001,10 +788,9 @@ static int internal_modify_qp(struct ib_
 			      int attr_mask, int smi_reset2init)
 {
 	enum ib_qp_state qp_cur_state = 0, qp_new_state = 0;
-	int req_qp_attr_mask = 0,
-		opt_qp_attr_mask = 0, cnt = 0, qp_attr_idx = 0, retcode = 0;
+	int cnt = 0, qp_attr_idx = 0, retcode = 0;
 
-	struct ehca_modqp_statetrans qp_state_xsit={.statetrans=0};
+	enum ib_qp_statetrans statetrans;
 	struct hcp_modify_qp_control_block *mqpcb = NULL;
 	struct ehca_qp *my_qp = NULL;
 	struct ehca_shca *shca = NULL;
@@ -1100,18 +886,10 @@ static int internal_modify_qp(struct ib_
 	     "new qp_state=%x attribute_mask=%x",
 	     my_qp, ibqp->qp_num, qp_cur_state, attr->qp_state, attr_mask);
 
-	if (attr_mask & IB_QP_STATE) {
-		if (attr->qp_state < IB_QPS_RESET ||
-		    attr->qp_state > IB_QPS_ERR) {
-			retcode = -EINVAL;
-			EDEB_ERR(4, "Invalid new qp state attr->qp_state=%x "
-				 "ehca_qp=%p qp_num=%x",
-				 attr->qp_state, my_qp, ibqp->qp_num);
-			goto modify_qp_exit1;
-		}
-		qp_new_state = attr->qp_state;
-	} else
-		qp_new_state = qp_cur_state;
+	qp_new_state = attr_mask & IB_QP_CUR_STATE ? attr->qp_state : qp_cur_state;
+
+	if (!ib_modify_qp_is_ok(qp_cur_state, qp_new_state, ibqp->qp_type, attr_mask))
+		return -EINVAL;
 
 	if ((mqpcb->qp_state = ib2ehca_qp_state(qp_new_state))) {
 		update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_STATE, 1);
@@ -1124,14 +902,14 @@ static int internal_modify_qp(struct ib_
 	}
 
 	/* retrieve state transition struct to get req and opt attrs */
-	if (get_modqp_statetrans(qp_cur_state,
-				 qp_new_state, &qp_state_xsit) < 0) {
+	statetrans = get_modqp_statetrans(qp_cur_state, qp_new_state);
+	if (statetrans < 0) {
 		retcode = -EINVAL;
 		EDEB_ERR(4, "<INVALID STATE CHANGE> qp_cur_state=%x "
 			 "new_qp_state=%x State_xsition=%x "
 			 "ehca_qp=%p qp_num=%x",
 			 qp_cur_state, qp_new_state,
-			 qp_state_xsit.statetrans, my_qp, ibqp->qp_num);
+			 statetrans, my_qp, ibqp->qp_num);
 		goto modify_qp_exit1;
 	}
 
@@ -1144,35 +922,14 @@ static int internal_modify_qp(struct ib_
 		goto modify_qp_exit1;
 	}
 
-	req_qp_attr_mask = qp_state_xsit.req_attr[qp_attr_idx];
-	opt_qp_attr_mask = qp_state_xsit.opt_attr[qp_attr_idx];
-
-	if ((attr_mask & req_qp_attr_mask) != req_qp_attr_mask) {
-		retcode = -EINVAL;
-		EDEB_ERR(4, "<INVALID required MASK> ehca_qp=%p qp_num=%x "
-			 "req_mask=%x opt_mask=%x submitted_mask=%x "
-			 "qp_type=%x",
-			 my_qp, ibqp->qp_num,
-			 req_qp_attr_mask, opt_qp_attr_mask,
-			 attr_mask, ibqp->qp_type);
-		goto modify_qp_exit1;
-	} else if ((attr_mask & ~(req_qp_attr_mask | opt_qp_attr_mask))) {
-		EDEB(7, "<optional MASK> more attributes "
-		     "specified than allowed!!! req_mask=%x opt_mask=%x "
-		     "submitted_mask=%x",
-		     req_qp_attr_mask, opt_qp_attr_mask, attr_mask);
-	}
-
-	EDEB(7, "ehca_qp=%p qp_num=%x <VALID STATE CHANGE> "
-	     "req_mask=%x opt_mask=%x qp_state_xsit=%x ",
-	     my_qp, ibqp->qp_num, req_qp_attr_mask,
-	     opt_qp_attr_mask, qp_state_xsit.statetrans);
+	EDEB(7, "ehca_qp=%p qp_num=%x <VALID STATE CHANGE> qp_state_xsit=%x ",
+	     my_qp, ibqp->qp_num, statetrans);
 
 	/* sqe -> rts: set purge bit of bad wqe before actual trans */
 	if ((my_qp->ehca_qp_core.qp_type == IB_QPT_UD
 	     || my_qp->ehca_qp_core.qp_type == IB_QPT_GSI
 	     || my_qp->ehca_qp_core.qp_type == IB_QPT_SMI)
-	    && qp_state_xsit.statetrans == IB_QPST_SQE2RTS) {
+	    && statetrans == IB_QPST_SQE2RTS) {
 		/* mark next free wqe if kernel */
 		if (my_qp->uspace_squeue == 0) {
 			struct ehca_wqe *wqe = NULL;
@@ -1198,13 +955,13 @@ static int internal_modify_qp(struct ib_
 	/* enable RDMA_Atomic_Control if reset->init und reliable con
 	   this is necessary since gen2 does not provide that flag,
 	   but pHyp requires it */
-	if (qp_state_xsit.statetrans == IB_QPST_RESET2INIT &&
+	if (statetrans == IB_QPST_RESET2INIT &&
 	    (ibqp->qp_type == IB_QPT_RC || ibqp->qp_type == IB_QPT_UC)) {
 		mqpcb->rdma_atomic_ctrl = 3;
 		update_mask |= EHCA_BMASK_SET(MQPCB_MASK_RDMA_ATOMIC_CTRL, 1);
 	}
 	/* circ. pHyp requires #RDMA/Atomic Responder Resources for UC INIT -> RTR */
-	if (qp_state_xsit.statetrans == IB_QPST_INIT2RTR &&
+	if (statetrans == IB_QPST_INIT2RTR &&
 	    (ibqp->qp_type == IB_QPT_UC) &&
 	    !(attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)) {
 		mqpcb->rdma_nr_atomic_resp_res = 1; /* default to 1 */
@@ -1439,15 +1196,15 @@ static int internal_modify_qp(struct ib_
 	if ((my_qp->ehca_qp_core.qp_type == IB_QPT_UD
 	     || my_qp->ehca_qp_core.qp_type == IB_QPT_GSI
 	     || my_qp->ehca_qp_core.qp_type == IB_QPT_SMI)
-	    && qp_state_xsit.statetrans == IB_QPST_SQE2RTS) {
+	    && statetrans == IB_QPST_SQE2RTS) {
 		/* doorbell to reprocessing wqes */
 		iosync(); /* serialize GAL register access */
 		hipz_update_SQA(&my_qp->ehca_qp_core, bad_wqe_cnt-1);
 		EDEB(6, "doorbell for %x wqes", bad_wqe_cnt);
 	}
 
-	if (qp_state_xsit.statetrans == IB_QPST_RESET2INIT ||
-	    qp_state_xsit.statetrans == IB_QPST_INIT2INIT) {
+	if (statetrans == IB_QPST_RESET2INIT ||
+	    statetrans == IB_QPST_INIT2INIT) {
 		mqpcb->qp_enable = TRUE;
 		mqpcb->qp_state = EHCA_QPS_INIT;
 		update_mask = 0;
@@ -1475,7 +1232,7 @@ static int internal_modify_qp(struct ib_
 		}
 	}
 
-	if (qp_state_xsit.statetrans == IB_QPST_ANY2RESET) {
+	if (statetrans == IB_QPST_ANY2RESET) {
 		ipz_QEit_reset(&my_qp->ehca_qp_core.ipz_rqueue);
 		ipz_QEit_reset(&my_qp->ehca_qp_core.ipz_squeue);
 	}



More information about the general mailing list