[ofa-general] [PATCH] mad.c: Fix memory leak in switch handling and improve error handling in ib_mad_recv_done_handler

Hal Rosenstock hal.rosenstock at gmail.com
Tue Jul 31 03:39:34 PDT 2007


mad.c: Fix memory leak in switch handling and improve error handling in
ib_mad_recv_done_handler. Also, eliminate no longer needed return value
in agent.c:agent_send_response.

Signed-off-by: Suresh Shelvapille <suri at baymicrosystems.com>
Signed-off-by: Hal Rosenstock <hal.rosenstock at gmail.com>

diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index db2633e..4c1a1ca 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -78,15 +78,14 @@ ib_get_agent_port(struct ib_device *device, int port_num)
       return entry;
 }

-int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
-                       struct ib_wc *wc, struct ib_device *device,
-                       int port_num, int qpn)
+void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
+                        struct ib_wc *wc, struct ib_device *device,
+                        int port_num, int qpn)
 {
       struct ib_agent_port_private *port_priv;
       struct ib_mad_agent *agent;
       struct ib_mad_send_buf *send_buf;
       struct ib_ah *ah;
-       int ret;
       struct ib_mad_send_wr_private *mad_send_wr;

       if (device->node_type == RDMA_NODE_IB_SWITCH)
@@ -96,23 +95,21 @@ int agent_send_response(struct ib_mad *mad, struct
ib_grh *grh,

       if (!port_priv) {
               printk(KERN_ERR SPFX "Unable to find port agent\n");
-               return -ENODEV;
+               return;
       }

       agent = port_priv->agent[qpn];
       ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num);
       if (IS_ERR(ah)) {
-               ret = PTR_ERR(ah);
-               printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret);
-               return ret;
+               printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n");
+               return;
       }

       send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
                                     IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
                                     GFP_KERNEL);
       if (IS_ERR(send_buf)) {
-               ret = PTR_ERR(send_buf);
-               printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret);
+               printk(KERN_ERR SPFX "ib_create_send_mad error\n");
               goto err1;
       }

@@ -126,16 +123,16 @@ int agent_send_response(struct ib_mad *mad,
struct ib_grh *grh,
               mad_send_wr->send_wr.wr.ud.port_num = port_num;
       }

-       if ((ret = ib_post_send_mad(send_buf, NULL))) {
-               printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret);
+       if (ib_post_send_mad(send_buf, NULL)) {
+               printk(KERN_ERR SPFX "ib_post_send_mad error\n");
               goto err2;
       }
-       return 0;
+       return;
 err2:
       ib_free_send_mad(send_buf);
 err1:
       ib_destroy_ah(ah);
-       return ret;
+       return;
 }

 static void agent_send_handler(struct ib_mad_agent *mad_agent,
diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
index 86d72fa..fb9ed14 100644
--- a/drivers/infiniband/core/agent.h
+++ b/drivers/infiniband/core/agent.h
@@ -46,8 +46,8 @@ extern int ib_agent_port_open(struct ib_device
*device, int port_num);

 extern int ib_agent_port_close(struct ib_device *device, int port_num);

-extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
-                              struct ib_wc *wc, struct ib_device *device,
-                              int port_num, int qpn);
+extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
+                               struct ib_wc *wc, struct ib_device *device,
+                               int port_num, int qpn);

 #endif /* __AGENT_H_ */
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index bc547f1..f82900d 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1842,16 +1842,11 @@ static void ib_mad_recv_done_handler(struct
ib_mad_port_private *port_priv,
 {
       struct ib_mad_qp_info *qp_info;
       struct ib_mad_private_header *mad_priv_hdr;
-       struct ib_mad_private *recv, *response;
+       struct ib_mad_private *recv, *response = NULL;
       struct ib_mad_list_head *mad_list;
       struct ib_mad_agent_private *mad_agent;
       int port_num;

-       response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
-       if (!response)
-               printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
-                      "for response buffer\n");
-
       mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
       qp_info = mad_list->mad_queue->qp_info;
       dequeue_mad(mad_list);
@@ -1879,6 +1874,13 @@ static void ib_mad_recv_done_handler(struct
ib_mad_port_private *port_priv,
       if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
               goto out;

+       response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
+       if (!response) {
+               printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
+                      "for response buffer\n");
+               goto out;
+       }
+
       if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH)
               port_num = wc->port_num;
       else
@@ -1914,12 +1916,11 @@ static void ib_mad_recv_done_handler(struct
ib_mad_port_private *port_priv,
                       response->header.recv_wc.recv_buf.mad =
&response->mad.mad;
                       response->header.recv_wc.recv_buf.grh = &response->grh;

-                       if (!agent_send_response(&response->mad.mad,
-                                                &response->grh, wc,
-                                                port_priv->device,
-
smi_get_fwd_port(&recv->mad.smp),
-                                                qp_info->qp->qp_num))
-                               response = NULL;
+                       agent_send_response(&response->mad.mad,
+                                           &response->grh, wc,
+                                           port_priv->device,
+                                           smi_get_fwd_port(&recv->mad.smp),
+                                           qp_info->qp->qp_num);

                       goto out;
               }
@@ -1930,15 +1931,6 @@ local:
       if (port_priv->device->process_mad) {
               int ret;

-               if (!response) {
-                       printk(KERN_ERR PFX "No memory for response MAD\n");
-                       /*
-                        * Is it better to assume that
-                        * it wouldn't be processed ?
-                        */
-                       goto out;
-               }
-
               ret = port_priv->device->process_mad(port_priv->device, 0,
                                                    port_priv->port_num,
                                                    wc, &recv->grh,



More information about the general mailing list