[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