[ofw] [PATCH 4/4] MAD: fix issues routing vendor MADs

Sean Hefty sean.hefty at intel.com
Fri May 8 11:32:30 PDT 2009


Only dispatch received vendor defined MADs to the HCA driver if the
management class is one of the MLX vendor defined classes.

When dispatching MADs locally that are not handled by the HCA driver,
copy the sent MAD data into the received MAD buffer.  Also initialize
the address information of the dispatched MAD, so that replies can be
routed correctly back to the sender.  If a MAD is not handled by the
HCA driver and cannot be dispatched, return the MAD to the MAD pool
to avoid leaking MADs.

Finally, we simplify the MAD dispatch code.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
diff -up -r -X \mshefty\scm\winof\trunk\docs\dontdiff.txt -I '\$Id:' trunk\core\al/al_mad.c branches\winverbs\core\al/al_mad.c
--- trunk\core\al/al_mad.c	2009-01-26 09:34:31.125875000 -0800
+++ branches\winverbs\core\al/al_mad.c	2009-05-07 10:27:30.082632500 -0700
@@ -1027,7 +1027,6 @@ __use_tid_routing(
 	IN		const	ib_mad_t* const				p_mad_hdr,
 	IN		const	boolean_t					are_we_sender )
 {
-	ib_rmpp_mad_t		*p_rmpp_mad;
 	boolean_t			is_orig;
 
 	AL_ENTER( AL_DBG_MAD_SVC );
@@ -1039,45 +1038,10 @@ __use_tid_routing(
 		return FALSE;
 	}
 
-	/*
-	 * Determine originator for a sent MAD.  Received MADs are just the
-	 * opposite.
-	 */
-
-	/* Non-DATA RMPP MADs are handled differently. */
-	p_rmpp_mad = (ib_rmpp_mad_t*)p_mad_hdr;
-	if( (p_mad_hdr->mgmt_class == IB_MCLASS_SUBN_ADM) &&
-		( ib_rmpp_is_flag_set( p_rmpp_mad, IB_RMPP_FLAG_ACTIVE ) &&
-		(p_rmpp_mad->rmpp_type != IB_RMPP_TYPE_DATA) ) )
-	{
-		/*
-		 * We need to distinguish between ACKs sent after receiving
-		 * a request, versus ACKs sent after receiving a response.  ACKs
-		 * to a request are from the responder.  ACKs to a response are
-		 * from the originator.
-
-		 * Note that we assume STOP and ABORT packets are initiated by
-		 * receivers.  If both senders and receivers can
-		 * initiate STOP and ABORT MADs, then we can't distinguish which
-		 * transaction is associated with the MAD.  The TID for a
-		 * send and receive can be the same.
-		 */
-		is_orig = !ib_mad_is_response( p_mad_hdr );
-	}
+	if (are_we_sender)
+		is_orig = !ib_mad_is_response(p_mad_hdr);
 	else
-	{
-		/*
-		 * See if the MAD is being sent in response to a previous MAD.  If
-		 * it is, then we're NOT the originator.  Note that trap repress
-		 * MADs are responses, even though the response bit isn't set.
-		 */
-		is_orig = !( ib_mad_is_response( p_mad_hdr ) ||
-			(p_mad_hdr->method == IB_MAD_METHOD_TRAP_REPRESS) );
-	}
-
-	/* If we're the receiver, toggle the result. */
-	if( !are_we_sender )
-		is_orig = !is_orig;
+		is_orig = ib_mad_is_response(p_mad_hdr);
 
 	AL_EXIT( AL_DBG_MAD_SVC );
 	return is_orig;
@@ -2221,12 +2192,9 @@ __mad_svc_recv_done(
 	}
 
 	/*
-	 * See if the MAD was sent in response to a previously sent MAD.  Note
-	 * that trap repress messages are responses, even though the response
-	 * bit isn't set.
+	 * See if the MAD was sent in response to a previously sent MAD.
 	 */
-	if( ib_mad_is_response( p_mad_hdr ) ||
-		(p_mad_hdr->method == IB_MAD_METHOD_TRAP_REPRESS) )
+	if( ib_mad_is_response( p_mad_hdr ) )
 	{
 		/* Process the received response. */
 		__process_recv_resp( h_mad_svc, p_mad_element );
diff -up -r -X \mshefty\scm\winof\trunk\docs\dontdiff.txt -I '\$Id:' trunk\core\al/kernel/al_smi.c
branches\winverbs\core\al/kernel/al_smi.c
--- trunk\core\al/kernel/al_smi.c	2009-01-26 09:34:30.250875000 -0800
+++ branches\winverbs\core\al/kernel/al_smi.c	2009-05-07 15:53:12.270907500 -0700
@@ -172,11 +172,11 @@ process_mad_recv(
 	IN				spl_qp_svc_t*				p_spl_qp_svc,
 	IN				ib_mad_element_t*			p_mad_element );
 
-mad_route_t
+static mad_route_t
 route_recv_smp(
 	IN				ib_mad_element_t*			p_mad_element );
 
-mad_route_t
+static mad_route_t
 route_recv_smp_attr(
 	IN				ib_mad_element_t*			p_mad_element );
 
@@ -184,12 +184,12 @@ mad_route_t
 route_recv_dm_mad(
 	IN				ib_mad_element_t*			p_mad_element );
 
-mad_route_t
-route_recv_gmp(
+static mad_route_t
+route_recv_bm(
 	IN				ib_mad_element_t*			p_mad_element );
 
-mad_route_t
-route_recv_gmp_attr(
+static mad_route_t
+route_recv_perf(
 	IN				ib_mad_element_t*			p_mad_element );
 
 ib_api_status_t
@@ -2234,6 +2234,7 @@ fwd_local_mad(
 	ib_mad_t*				p_mad;
 	ib_smp_t*				p_smp;
 	al_mad_send_t*			p_mad_send;
+	ib_mad_element_t*		p_send_mad;
 	ib_mad_element_t*		p_mad_response = NULL;
 	ib_mad_t*				p_mad_response_buf;
 	ib_api_status_t			status = IB_SUCCESS;
@@ -2263,6 +2264,8 @@ fwd_local_mad(
 			return status;
 		}
 		p_mad_response_buf = p_mad_response->p_mad_buf;
+		/* Copy MAD to dispatch locally in case CA doesn't handle it. */
+		*p_mad_response_buf = *p_mad;
 	}
 	else
 	{
@@ -2399,9 +2402,17 @@ fwd_local_mad(
 		
 
 		/* Construct the receive MAD element. */
-		p_mad_response->status		= IB_WCS_SUCCESS;
-		p_mad_response->remote_qp	= p_mad_wr->send_wr.dgrm.ud.remote_qp;
-		p_mad_response->remote_lid	= p_spl_qp_svc->base_lid;
+		p_send_mad = p_mad_send->p_send_mad;
+		p_mad_response->status = IB_WCS_SUCCESS;
+		p_mad_response->grh_valid = p_send_mad->grh_valid;
+		if( p_mad_response->grh_valid )
+			*p_mad_response->p_grh  = *p_send_mad->p_grh;
+		p_mad_response->path_bits   = p_send_mad->path_bits;
+		p_mad_response->pkey_index  = p_send_mad->pkey_index;
+		p_mad_response->remote_lid  = p_send_mad->remote_lid;
+		p_mad_response->remote_qkey = p_send_mad->remote_qkey;
+		p_mad_response->remote_qp   = p_send_mad->remote_qp;
+		p_mad_response->remote_sl   = p_send_mad->remote_sl;
 		if( p_mad_wr->send_wr.send_opt & IB_RECV_OPT_IMMEDIATE )
 		{
 			p_mad_response->immediate_data = p_mad_wr->send_wr.immediate_data;
@@ -2413,6 +2424,8 @@ fwd_local_mad(
 		 * the send.  This guarantees that the send request cannot time out.
 		 */
 		status = mad_disp_recv_done( p_spl_qp_svc->h_mad_disp, p_mad_response );
+		if( status != IB_SUCCESS )
+			ib_put_mad( p_mad_response );
 	}
 	
 	__complete_send_mad( p_spl_qp_svc->h_mad_disp, p_mad_wr,IB_WCS_SUCCESS);
@@ -2937,35 +2950,19 @@ process_mad_recv(
 			break;
 
 		case IB_MCLASS_PERF:
-			/* Process the received GMP. */
-			switch( p_mad_element->p_mad_buf->method )
-			{
-			case IB_MAD_METHOD_GET:
-			case IB_MAD_METHOD_SET:
-				route = ROUTE_LOCAL;
-				break;
-			default:
-				break;
-			}
+			route = route_recv_perf( p_mad_element );
 			break;
 
 		case IB_MCLASS_BM:
-			route = route_recv_gmp( p_mad_element );
+			route = route_recv_bm( p_mad_element );
 			break;
 
-		case IB_MCLASS_SUBN_ADM:
-		case IB_MCLASS_DEV_MGMT:
-		case IB_MCLASS_COMM_MGMT:
-		case IB_MCLASS_SNMP:
+		case IB_MLX_VENDOR_CLASS1:
+		case IB_MLX_VENDOR_CLASS2:
+			route = ROUTE_LOCAL;
 			break;
 
 		default:
-			/* Route vendor specific MADs to the HCA provider. */
-			if( ib_class_is_vendor_specific(
-				p_mad_element->p_mad_buf->mgmt_class ) )
-			{
-				route = route_recv_gmp( p_mad_element );
-			}
 			break;
 		}
 	}
@@ -2989,7 +2986,7 @@ process_mad_recv(
 /*
  * Route a received SMP.
  */
-mad_route_t
+static mad_route_t
 route_recv_smp(
 	IN				ib_mad_element_t*			p_mad_element )
 {
@@ -3054,7 +3051,7 @@ route_recv_smp(
 /*
  * Route received SMP attributes.
  */
-mad_route_t
+static mad_route_t
 route_recv_smp_attr(
 	IN				ib_mad_element_t*			p_mad_element )
 {
@@ -3090,72 +3087,38 @@ route_recv_smp_attr(
 }
 
 
-/*
- * Route a received GMP.
- */
-mad_route_t
-route_recv_gmp(
+static mad_route_t
+route_recv_bm(
 	IN				ib_mad_element_t*			p_mad_element )
 {
-	mad_route_t				route;
-
-	AL_ENTER( AL_DBG_SMI );
-
-	CL_ASSERT( p_mad_element );
-
-	/* Process the received GMP. */
 	switch( p_mad_element->p_mad_buf->method )
 	{
 	case IB_MAD_METHOD_GET:
 	case IB_MAD_METHOD_SET:
-		/* Route vendor specific MADs to the HCA provider. */
-		if( ib_class_is_vendor_specific(
-			p_mad_element->p_mad_buf->mgmt_class ) )
-		{
-			route = ROUTE_LOCAL;
-		}
-		else
-		{
-			route = route_recv_gmp_attr( p_mad_element );
-		}
+		if( p_mad_element->p_mad_buf->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO )
+			return ROUTE_LOCAL;
 		break;
-
 	default:
-		route = ROUTE_DISPATCHER;
 		break;
 	}
-
-	AL_EXIT( AL_DBG_SMI );
-	return route;
+	return ROUTE_DISPATCHER;
 }
 
-
-
-/*
- * Route received GMP attributes.
- */
-mad_route_t
-route_recv_gmp_attr(
+static mad_route_t
+route_recv_perf(
 	IN				ib_mad_element_t*			p_mad_element )
 {
-	mad_route_t				route;
-
-	AL_ENTER( AL_DBG_SMI );
-
-	CL_ASSERT( p_mad_element );
-
-	/* Process the received GMP attributes. */
-	if( p_mad_element->p_mad_buf->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO )
-		route = ROUTE_LOCAL;
-	else
-		route = ROUTE_DISPATCHER;
-
-	AL_EXIT( AL_DBG_SMI );
-	return route;
+	switch( p_mad_element->p_mad_buf->method )
+	{
+	case IB_MAD_METHOD_GET:
+	case IB_MAD_METHOD_SET:
+		return ROUTE_LOCAL;
+	default:
+		break;
+	}
+	return ROUTE_DISPATCHER;
 }
 
-
-
 /*
  * Forward a locally generated Subnet Management trap.
  */
@@ -3263,8 +3226,7 @@ recv_local_mad(
 	 * We need to get a response from the local HCA to this MAD only if this
 	 * MAD is not itself a response.
 	 */
-	p_mad_request->resp_expected = !( ib_mad_is_response( p_mad_hdr ) ||
-		( p_mad_hdr->method == IB_MAD_METHOD_TRAP_REPRESS ) );
+	p_mad_request->resp_expected = !ib_mad_is_response( p_mad_hdr );
 	p_mad_request->timeout_ms = LOCAL_MAD_TIMEOUT;
 	p_mad_request->send_opt	= IB_SEND_OPT_LOCAL;
 
diff -up -r -X \mshefty\scm\winof\trunk\docs\dontdiff.txt -I '\$Id:' trunk\inc\iba/ib_types.h branches\winverbs\inc\iba/ib_types.h
--- trunk\inc\iba/ib_types.h	2009-05-05 23:05:51.060250000 -0700
+++ branches\winverbs\inc\iba/ib_types.h	2009-05-07 15:31:55.012120700 -0700
@@ -3795,8 +3798,8 @@ ib_mad_is_response(
 	IN		const	ib_mad_t* const				p_mad )
 {
 	CL_ASSERT( p_mad );
-	return( (p_mad->method & IB_MAD_METHOD_RESP_MASK) ==
-			IB_MAD_METHOD_RESP_MASK );
+	return ((p_mad->method & IB_MAD_METHOD_RESP_MASK) ||
+			(p_mad->method == IB_MAD_METHOD_TRAP_REPRESS));
 }
 /*
 * PARAMETERS





More information about the ofw mailing list