[ofa-general] [PATCH] infiniband/core: Enable loopback of DR SMP responses from userspace

swelch at systemfabricworks.com swelch at systemfabricworks.com
Thu Aug 30 19:46:28 PDT 2007



  The local loopback of a DR SMP response is limited to those that originate at the driver specific SMA implementation as a result of an invocation of the drivers process_mad() function.  This patch enables a DR SMP response originating elsewhere to be forwarded/looped back to the local management stack as well.  In this case the driver specific process_mad() function does not consume or process the MAD so the original MAD is to be treated like an incoming receive and it must be manually copied to the buffer that is to be handed off the local agent.

  The stimulus for this change is to provide support for the forwarding of DR SMP responses to the local management stack via the user space MAD library.  This will facilitate development of userspace applications utilizing the MTHCA router mode enable driver.

Signed-off-by: Steve Welch <swelch at systemfabricworks.com>
---
 drivers/infiniband/core/mad.c                |    4 +++-
 drivers/infiniband/core/smi.h                |   14 ++++++++++++++
 2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 6f42877..9ec910b 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -701,7 +701,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
 	}
 
 	/* Check to post send on QP or process locally */
-	if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD)
+	if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD &&
+	    smi_check_local_resp_smp(smp, device) == IB_SMI_DISCARD)
 		goto out;
 
 	local = kmalloc(sizeof *local, GFP_ATOMIC);
@@ -754,6 +755,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
 		if (port_priv) {
 			mad_priv->mad.mad.mad_hdr.tid =
 				((struct ib_mad *)smp)->mad_hdr.tid;
+			memcpy(&mad_priv->mad.mad, smp, sizeof(struct ib_mad));
 			recv_mad_agent = find_mad_agent(port_priv,
 						        &mad_priv->mad.mad);
 		}
diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h
index 1cfc298..d96fc8e 100644
--- a/drivers/infiniband/core/smi.h
+++ b/drivers/infiniband/core/smi.h
@@ -71,4 +71,18 @@ static inline enum smi_action smi_check_local_smp(struct ib_smp *smp,
 		(smp->hop_ptr == smp->hop_cnt + 1)) ?
 		IB_SMI_HANDLE : IB_SMI_DISCARD);
 }
+
+/*
+ * Return 1 if the SMP response should be handled by the local management stack
+ */
+static inline enum smi_action smi_check_local_resp_smp(struct ib_smp *smp,
+						       struct ib_device *device)
+{
+	/* C14-13:3 -- We're at the end of the DR segment of path */
+	/* C14-13:4 -- Hop Pointer == 0 -> give to SM */
+	return ((device->process_mad &&
+		ib_get_smp_direction(smp) &&
+		!smp->hop_ptr) ? IB_SMI_HANDLE : IB_SMI_DISCARD);
+}
+
 #endif	/* __SMI_H_ */



More information about the general mailing list