]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ib_core: More fixes to ib_sa_add_one error flow
authorJack Morgenstein <jackm@dev.mellanox.co.il>
Thu, 14 Nov 2013 15:35:06 +0000 (17:35 +0200)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 7 Jul 2015 21:45:14 +0000 (14:45 -0700)
commit 0e7377eed fixed a resource leak of mad agents in
the ib_sa_add_one error flow.  However, the fix allowed
ib_mad_unregister_agent to be called in a case where the
ib_mad_register_agent request failed (resulting in an
illegal pointer in the agent field).  This caused a kernel
Oops in the error flow.

Fix this by calling ib_unregister_mad_agent only for cases where
ib_register_mad_agent succeeded.

In addition, separate the ib_register_event_handler() call error
flow from the loop error flow. If the call to
ib_register_event_handler fails, the client data must be reset
to NULL, (in case at some point ib_register_event_handler() is
modified so that it may return a non-zero (error) value).

Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
(Ported from Mellanox OFED 2.4)

Signed-off-by: Mukesh Kacker <mukesh.kacker@oracle.com>
drivers/infiniband/core/sa_query.c

index a58788ff59a1c9653a9d277aee1587fb8b1e0022..80461aff9c66e57bea715457647f145a4a76c202 100644 (file)
@@ -1202,7 +1202,7 @@ static void ib_sa_add_one(struct ib_device *device)
 
        INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
        if (ib_register_event_handler(&sa_dev->event_handler))
-               goto err;
+               goto reg_err;
 
        for (i = 0; i <= e - s; ++i)
                if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND)
@@ -1210,9 +1210,13 @@ static void ib_sa_add_one(struct ib_device *device)
 
        return;
 
+reg_err:
+       ib_set_client_data(device, &sa_client, NULL);
+       i = e - s;
 err:
        for (; i >= 0; --i)
-               if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND)
+               if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND &&
+                   !IS_ERR(sa_dev->port[i].agent))
                        ib_unregister_mad_agent(sa_dev->port[i].agent);
 
        kfree(sa_dev);