[openib-general] [PATCH] Problem with directed route SMPs with beginning or ending LID routed parts

Ralph Campbell ralphc at pathscale.com
Thu Jan 12 18:44:40 PST 2006


I have only done basic testing (i.e., the link comes up and IPoIB still works)
but I think this fixes the problem.

Signed-off-by: Ralph Campbell <ralphc at pathscale.com>

Index: include/rdma/ib_mad.h
===================================================================
--- include/rdma/ib_mad.h	(revision 4978)
+++ include/rdma/ib_mad.h	(working copy)
@@ -596,7 +596,7 @@
  */
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 					    u32 remote_qpn, u16 pkey_index,
-					    int rmpp_active,
+					    int rmpp_active, int directed_route,
 					    int hdr_len, int data_len,
 					    gfp_t gfp_mask);
 
Index: core/user_mad.c
===================================================================
--- core/user_mad.c	(revision 4978)
+++ core/user_mad.c	(working copy)
@@ -51,6 +51,7 @@
 
 #include <rdma/ib_mad.h>
 #include <rdma/ib_user_mad.h>
+#include <rdma/ib_smi.h>
 
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
@@ -339,6 +340,8 @@
 	__be64 *tid;
 	int ret, length, hdr_len, copy_offset;
 	int rmpp_active, has_rmpp_header;
+	int directed_route;
+	struct ib_smp *smp;
 
 	if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
 		return -EINVAL;
@@ -415,9 +418,20 @@
 		goto err_ah;
 	}
 
+	/*
+	 * Directed route handling starts if the initial LID routed part of
+	 * a request or the ending LID routed part of a response is empty.
+	 * See section 14.2.2, Vol 1 IB spec.
+	 */
+	smp = (struct ib_smp *) packet->mad.data;
+	if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+		directed_route = (ib_get_smp_direction(smp) ?
+			smp->dr_dlid : smp->dr_slid) == IB_LID_PERMISSIVE;
+	else
+		directed_route = 0;
 	packet->msg = ib_create_send_mad(agent,
 					 be32_to_cpu(packet->mad.hdr.qpn),
-					 0, rmpp_active,
+					 0, rmpp_active, directed_route,
 					 hdr_len, length - hdr_len,
 					 GFP_KERNEL);
 	if (IS_ERR(packet->msg)) {
Index: core/agent.c
===================================================================
--- core/agent.c	(revision 4978)
+++ core/agent.c	(working copy)
@@ -103,6 +103,7 @@
 	struct ib_mad_send_buf *send_buf;
 	struct ib_ah *ah;
 	int ret;
+	int directed_route;
 
 	port_priv = ib_get_agent_port(device, port_num);
 	if (!port_priv) {
@@ -118,7 +119,20 @@
 		return ret;
 	}
 
+	/*
+	 * Directed route handling starts if the initial LID routed part of
+	 * a request or the ending LID routed part of a response is empty.
+	 * See section 14.2.2, Vol 1 IB spec.
+	 */
+	if (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+		struct ib_smp *smp = (struct ib_smp *) mad;
+
+		directed_route = (ib_get_smp_direction(smp) ?
+			smp->dr_dlid : smp->dr_slid) == IB_LID_PERMISSIVE;
+	} else
+		directed_route = 0;
 	send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
+				      directed_route,
 				      IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
 				      GFP_KERNEL);
 	if (IS_ERR(send_buf)) {
Index: core/sa_query.c
===================================================================
--- core/sa_query.c	(revision 4978)
+++ core/sa_query.c	(working copy)
@@ -574,7 +574,7 @@
 		return -ENOMEM;
 
 	query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-						     0, IB_MGMT_SA_HDR,
+						     0, 0, IB_MGMT_SA_HDR,
 						     IB_MGMT_SA_DATA, gfp_mask);
 	if (!query->sa_query.mad_buf) {
 		ret = -ENOMEM;
@@ -695,7 +695,7 @@
 		return -ENOMEM;
 
 	query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-						     0, IB_MGMT_SA_HDR,
+						     0, 0, IB_MGMT_SA_HDR,
 						     IB_MGMT_SA_DATA, gfp_mask);
 	if (!query->sa_query.mad_buf) {
 		ret = -ENOMEM;
@@ -787,7 +787,7 @@
 		return -ENOMEM;
 
 	query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0,
-						     0, IB_MGMT_SA_HDR,
+						     0, 0, IB_MGMT_SA_HDR,
 						     IB_MGMT_SA_DATA, gfp_mask);
 	if (!query->sa_query.mad_buf) {
 		ret = -ENOMEM;
Index: core/ping.c
===================================================================
--- core/ping.c	(revision 4978)
+++ core/ping.c	(working copy)
@@ -127,7 +127,7 @@
 	}
 
 	msg = ib_create_send_mad(mad_agent, mad_recv_wc->wc->src_qp,
-				 mad_recv_wc->wc->pkey_index, 0,
+				 mad_recv_wc->wc->pkey_index, 0, 0,
 				 IB_MGMT_VENDOR_HDR,
 				 mad_recv_wc->mad_len - IB_MGMT_VENDOR_HDR,
 				 GFP_KERNEL);
Index: core/mad_rmpp.c
===================================================================
--- core/mad_rmpp.c	(revision 4978)
+++ core/mad_rmpp.c	(working copy)
@@ -138,8 +138,9 @@
 	int ret;
 
 	msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
-				 recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR,
-				 IB_MGMT_RMPP_DATA, GFP_KERNEL);
+				 recv_wc->wc->pkey_index, 1, 0,
+				 IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
+				 GFP_KERNEL);
 	if (!msg)
 		return;
 
@@ -163,7 +164,7 @@
 		return (void *) ah;
 
 	msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
-				 recv_wc->wc->pkey_index, 1,
+				 recv_wc->wc->pkey_index, 1, 0,
 				 IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
 				 GFP_KERNEL);
 	if (IS_ERR(msg))
Index: core/mad.c
===================================================================
--- core/mad.c	(revision 4978)
+++ core/mad.c	(working copy)
@@ -665,7 +665,8 @@
 	struct ib_wc mad_wc;
 	struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
 
-	if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
+	if (mad_send_wr->directed_route &&
+	    !smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
 		ret = -EINVAL;
 		printk(KERN_ERR PFX "Invalid directed route\n");
 		goto out;
@@ -699,8 +700,7 @@
 	ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,
 				  (struct ib_mad *)smp,
 				  (struct ib_mad *)&mad_priv->mad);
-	switch (ret)
-	{
+	switch (ret) {
 	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
 		if (response_mad(&mad_priv->mad.mad) &&
 		    mad_agent_priv->agent.recv_handler) {
@@ -773,7 +773,7 @@
 
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 					    u32 remote_qpn, u16 pkey_index,
-					    int rmpp_active,
+					    int rmpp_active, int directed_route,
 					    int hdr_len, int data_len,
 					    gfp_t gfp_mask)
 {
@@ -818,6 +818,8 @@
 	mad_send_wr->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
 	mad_send_wr->send_wr.wr.ud.pkey_index = pkey_index;
 
+	mad_send_wr->directed_route = directed_route;
+
 	if (rmpp_active) {
 		struct ib_rmpp_mad *rmpp_mad = mad_send_wr->send_buf.mad;
 		rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
Index: core/mad_priv.h
===================================================================
--- core/mad_priv.h	(revision 4978)
+++ core/mad_priv.h	(working copy)
@@ -124,10 +124,11 @@
 	struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
 	__be64 tid;
 	unsigned long timeout;
-	int retries;
-	int retry;
-	int refcount;
+	unsigned int retries;
+	unsigned int retry;
+	unsigned int refcount;
 	enum ib_wc_status status;
+	int directed_route;
 
 	/* RMPP control */
 	int last_ack;
Index: core/cm.c
===================================================================
--- core/cm.c	(revision 4978)
+++ core/cm.c	(working copy)
@@ -177,7 +177,7 @@
 
 	m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, 
 			       cm_id_priv->av.pkey_index,
-			       0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+			       0, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
 			       GFP_ATOMIC);
 	if (IS_ERR(m)) {
 		ib_destroy_ah(ah);
@@ -207,7 +207,7 @@
 		return PTR_ERR(ah);
 
 	m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
-			       0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+			       0, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
 			       GFP_ATOMIC);
 	if (IS_ERR(m)) {
 		ib_destroy_ah(ah);
Index: hw/mthca/mthca_mad.c
===================================================================
--- hw/mthca/mthca_mad.c	(revision 4978)
+++ hw/mthca/mthca_mad.c	(working copy)
@@ -117,7 +117,8 @@
 	unsigned long flags;
 
 	if (agent) {
-		send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR,
+		send_buf = ib_create_send_mad(agent, qpn, 0, 0, 0,
+					      IB_MGMT_MAD_HDR,
 					      IB_MGMT_MAD_DATA, GFP_ATOMIC);
 		/*
 		 * We rely here on the fact that MLX QPs don't use the

-- 
Ralph Campbell <ralphc at pathscale.com>




More information about the general mailing list