[ofa-general] [PATCH] IB/core: ib_post_send_mad() returns zero but doesn't generate send completion
Ralph Campbell
ralph.campbell at qlogic.com
Fri Feb 27 13:45:57 PST 2009
If ib_post_send_mad() returns zero, it guarantees that there will be
a callback to the send_buf->mad_agent->send_handler() so that the
sender can call ib_free_send_mad(). Otherwise, the ib_mad_send_buf
will be leaked and the mad_agent reference count will never go to zero
and the IB device module cannot be unloaded.
The above can happen without this patch if process_mad() returns
(IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED).
If process_mad() returns IB_MAD_RESULT_SUCCESS and there is no agent
registered to receive the mad being sent, handle_outgoing_dr_smp()
returns zero which causes a MAD packet which is at the end of the
directed route to be incorrectly sent on the wire but doesn't cause
a hang since the HCA generates a send completion.
Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index dbcd285..62a99dc 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -742,9 +742,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
break;
case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
kmem_cache_free(ib_mad_cache, mad_priv);
- kfree(local);
- ret = 1;
- goto out;
+ break;
case IB_MAD_RESULT_SUCCESS:
/* Treat like an incoming receive MAD */
port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
@@ -755,10 +753,12 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
&mad_priv->mad.mad);
}
if (!port_priv || !recv_mad_agent) {
+ /*
+ * No receiving agent so drop packet and
+ * generate send completion.
+ */
kmem_cache_free(ib_mad_cache, mad_priv);
- kfree(local);
- ret = 0;
- goto out;
+ break;
}
local->mad_priv = mad_priv;
local->recv_mad_agent = recv_mad_agent;
More information about the general
mailing list