[openib-general] [PATCH] collapse MAD function calls
Sean Hefty
mshefty at ichips.intel.com
Fri Nov 12 16:45:09 PST 2004
This patch callapses several function calls into one when activating
the MAD QPs. This avoids repeated allocation/freeing of memory.
I have plans to examine the QP transitions to the reset
state to see if these are necessary and if a race condition exists
between shutting down a port and processing a receive completion.
- Sean
Index: core/mad.c
===================================================================
--- core/mad.c (revision 1222)
+++ core/mad.c (working copy)
@@ -90,8 +90,6 @@
struct ib_mad_send_wc *mad_send_wc);
static void timeout_sends(void *data);
static int solicited_mad(struct ib_mad *mad);
-static int ib_mad_change_qp_state_to_rts(struct ib_qp *qp,
- enum ib_qp_state cur_state);
/*
* Returns a ib_mad_port_private structure or NULL for a device/port
@@ -1396,13 +1394,21 @@
} else
ib_mad_send_done_handler(port_priv, wc);
} else {
+ struct ib_qp_attr *attr;
+
/* Transition QP to RTS and fail offending send */
- ret = ib_mad_change_qp_state_to_rts(qp_info->qp, IB_QPS_SQE);
- if (ret)
- printk(KERN_ERR PFX "mad_error_handler - unable to "
- "transition QP to RTS : %d\n", ret);
+ attr = kmalloc(sizeof *attr, GFP_KERNEL);
+ if (attr) {
+ attr->qp_state = IB_QPS_RTS;
+ ret = ib_modify_qp(qp_info->qp, attr, IB_QP_STATE);
+ kfree(attr);
+ if (ret)
+ printk(KERN_ERR PFX "mad_error_handler - "
+ "ib_modify_qp to RTS : %d\n", ret);
+ else
+ mark_sends_for_retry(qp_info);
+ }
ib_mad_send_done_handler(port_priv, wc);
- mark_sends_for_retry(qp_info);
}
}
@@ -1692,172 +1698,51 @@
}
/*
- * Return all the posted send MADs
- */
-static void ib_mad_return_posted_send_mads(struct ib_mad_qp_info *qp_info)
-{
- unsigned long flags;
-
- /* Just clear port send posted MAD list... revisit!!! */
- spin_lock_irqsave(&qp_info->send_queue.lock, flags);
- INIT_LIST_HEAD(&qp_info->send_queue.list);
- qp_info->send_queue.count = 0;
- INIT_LIST_HEAD(&qp_info->overflow_list);
- spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
-}
-
-/*
- * Modify QP into Init state
- */
-static inline int ib_mad_change_qp_state_to_init(struct ib_qp *qp)
-{
- int ret;
- struct ib_qp_attr *attr;
- int attr_mask;
-
- attr = kmalloc(sizeof *attr, GFP_KERNEL);
- if (!attr) {
- printk(KERN_ERR PFX "Couldn't allocate memory for "
- "ib_qp_attr\n");
- return -ENOMEM;
- }
-
- attr->qp_state = IB_QPS_INIT;
- /*
- * PKey index for QP1 is irrelevant but
- * one is needed for the Reset to Init transition.
- */
- attr->pkey_index = 0;
- /* QKey is 0 for QP0 */
- if (qp->qp_num == 0)
- attr->qkey = 0;
- else
- attr->qkey = IB_QP1_QKEY;
- attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_QKEY;
-
- ret = ib_modify_qp(qp, attr, attr_mask);
- kfree(attr);
-
- if (ret)
- printk(KERN_WARNING PFX "ib_mad_change_qp_state_to_init "
- "ret = %d\n", ret);
- return ret;
-}
-
-/*
- * Modify QP into Ready-To-Receive state
- */
-static inline int ib_mad_change_qp_state_to_rtr(struct ib_qp *qp)
-{
- int ret;
- struct ib_qp_attr *attr;
- int attr_mask;
-
- attr = kmalloc(sizeof *attr, GFP_KERNEL);
- if (!attr) {
- printk(KERN_ERR PFX "Couldn't allocate memory for "
- "ib_qp_attr\n");
- return -ENOMEM;
- }
-
- attr->qp_state = IB_QPS_RTR;
- attr_mask = IB_QP_STATE;
-
- ret = ib_modify_qp(qp, attr, attr_mask);
- kfree(attr);
-
- if (ret)
- printk(KERN_WARNING PFX "ib_mad_change_qp_state_to_rtr "
- "ret = %d\n", ret);
- return ret;
-}
-
-/*
- * Modify QP into Ready-To-Send state
- */
-static int ib_mad_change_qp_state_to_rts(struct ib_qp *qp,
- enum ib_qp_state cur_state)
-{
- int ret;
- struct ib_qp_attr *attr;
- int attr_mask;
-
- attr = kmalloc(sizeof *attr, GFP_KERNEL);
- if (!attr) {
- printk(KERN_ERR PFX "Couldn't allocate memory for "
- "ib_qp_attr\n");
- return -ENOMEM;
- }
- attr->qp_state = IB_QPS_RTS;
- attr_mask = IB_QP_STATE;
- if (cur_state == IB_QPS_RTR) {
- attr->sq_psn = IB_MAD_SEND_Q_PSN;
- attr_mask |= IB_QP_SQ_PSN;
- }
- ret = ib_modify_qp(qp, attr, attr_mask);
- kfree(attr);
-
- if (ret)
- printk(KERN_WARNING PFX "ib_mad_change_qp_state_to_rts "
- "ret = %d\n", ret);
- return ret;
-}
-
-/*
- * Modify QP into Reset state
+ * Start the port
*/
-static inline int ib_mad_change_qp_state_to_reset(struct ib_qp *qp)
+static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
{
- int ret;
+ int ret, i;
struct ib_qp_attr *attr;
- int attr_mask;
+ struct ib_qp *qp;
attr = kmalloc(sizeof *attr, GFP_KERNEL);
if (!attr) {
- printk(KERN_ERR PFX "Couldn't allocate memory for "
- "ib_qp_attr\n");
+ printk(KERN_ERR PFX "Couldn't kmalloc ib_qp_attr\n");
return -ENOMEM;
}
- attr->qp_state = IB_QPS_RESET;
- attr_mask = IB_QP_STATE;
-
- ret = ib_modify_qp(qp, attr, attr_mask);
- kfree(attr);
-
- if (ret)
- printk(KERN_WARNING PFX "ib_mad_change_qp_state_to_reset "
- "ret = %d\n", ret);
- return ret;
-}
-
-/*
- * Start the port
- */
-static int ib_mad_port_start(struct ib_mad_port_private *port_priv)
-{
- int ret, i, ret2;
-
for (i = 0; i < IB_MAD_QPS_CORE; i++) {
- ret = ib_mad_change_qp_state_to_init(port_priv->qp_info[i].qp);
+ qp = port_priv->qp_info[i].qp;
+ /*
+ * PKey index for QP1 is irrelevant but
+ * one is needed for the Reset to Init transition.
+ */
+ attr->qp_state = IB_QPS_INIT;
+ attr->pkey_index = 0;
+ attr->qkey = (qp->qp_num == 0) ? 0 : IB_QP1_QKEY;
+ ret = ib_modify_qp(qp, attr, IB_QP_STATE |
+ IB_QP_PKEY_INDEX | IB_QP_QKEY);
if (ret) {
printk(KERN_ERR PFX "Couldn't change QP%d state to "
- "INIT\n", i);
+ "INIT: %d\n", i, ret);
goto error;
}
- ret = ib_mad_change_qp_state_to_rtr(port_priv->qp_info[i].qp);
+ attr->qp_state = IB_QPS_RTR;
+ ret = ib_modify_qp(qp, attr, IB_QP_STATE);
if (ret) {
printk(KERN_ERR PFX "Couldn't change QP%d state to "
- "RTR\n", i);
+ "RTR: %d\n", i, ret);
goto error;
}
- ret = ib_mad_change_qp_state_to_rts(port_priv->qp_info[i].qp,
- IB_QPS_RTR);
+ attr->qp_state = IB_QPS_RTS;
+ attr->sq_psn = IB_MAD_SEND_Q_PSN;
+ ret = ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_SQ_PSN);
if (ret) {
printk(KERN_ERR PFX "Couldn't change QP%d state to "
- "RTS\n", i);
+ "RTS: %d\n", i, ret);
goto error;
}
}
@@ -1865,30 +1750,28 @@
ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
if (ret) {
printk(KERN_ERR PFX "Failed to request completion "
- "notification\n");
+ "notification: %d\n", ret);
goto error;
}
for (i = 0; i < IB_MAD_QPS_CORE; i++) {
ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL);
if (ret) {
- printk(KERN_ERR PFX "Couldn't post receive "
- "requests\n");
+ printk(KERN_ERR PFX "Couldn't post receive WRs\n");
goto error;
}
}
- return 0;
+ goto out;
error:
for (i = 0; i < IB_MAD_QPS_CORE; i++) {
+ attr->qp_state = IB_QPS_RESET;
+ ret = ib_modify_qp(port_priv->qp_info[i].qp, attr, IB_QP_STATE);
ib_mad_return_posted_recv_mads(&port_priv->qp_info[i]);
- ret2 = ib_mad_change_qp_state_to_reset(port_priv->
- qp_info[i].qp);
- if (ret2) {
- printk(KERN_ERR PFX "ib_mad_port_start: Couldn't "
- "change QP%d state to RESET\n", i);
- }
}
+
+out:
+ kfree(attr);
return ret;
}
@@ -1898,19 +1781,26 @@
static void ib_mad_port_stop(struct ib_mad_port_private *port_priv)
{
int i, ret;
+ struct ib_qp_attr *attr;
- for (i = 0; i < IB_MAD_QPS_CORE; i++) {
- ret = ib_mad_change_qp_state_to_reset(
- port_priv->qp_info[i].qp);
- if (ret) {
- printk(KERN_ERR PFX "ib_mad_port_stop: Couldn't change"
- " %s port %d QP%d state to RESET\n",
- port_priv->device->name, port_priv->port_num,
- i);
+ attr = kmalloc(sizeof *attr, GFP_KERNEL);
+ if (attr) {
+ attr->qp_state = IB_QPS_RESET;
+ for (i = 0; i < IB_MAD_QPS_CORE; i++) {
+ ret = ib_modify_qp(port_priv->qp_info[i].qp, attr,
+ IB_QP_STATE);
+ if (ret)
+ printk(KERN_ERR PFX "ib_mad_port_stop: "
+ "Couldn't change %s port %d QP%d "
+ "state to RESET\n",
+ port_priv->device->name,
+ port_priv->port_num, i);
}
- ib_mad_return_posted_recv_mads(&port_priv->qp_info[i]);
- ib_mad_return_posted_send_mads(&port_priv->qp_info[i]);
+ kfree(attr);
}
+
+ for (i = 0; i < IB_MAD_QPS_CORE; i++)
+ ib_mad_return_posted_recv_mads(&port_priv->qp_info[i]);
}
static void qp_event_handler(struct ib_event *event, void *qp_context)
More information about the general
mailing list