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>
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)
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);