[ofa-general] [PATCH 4/4 v2] multicast multiplexing - building spanning tree and removes obsolete code.

Slava Strebkov slavas at Voltaire.COM
Sun Jun 28 04:00:03 PDT 2009


Subject: [PATCH 4/4] Patch implements multicast multiplexing as proposed in the
 thread entitled "IPv6 and IPoIB scalability issue".
 This part (4) implements infrastructure management for
 building spanning tree and removes obsolete parts of code.
 Signed-off-by: Slava Strebkov <slavas at voltaire.com>

---
 opensm/include/opensm/osm_multicast.h |   14 +-
 opensm/include/opensm/osm_subnet.h    |   33 -----
 opensm/opensm/osm_mcast_mgr.c         |  247 ++++++++++++++++++++-------------
 opensm/opensm/osm_multicast.c         |   47 ------
 opensm/opensm/osm_sm.c                |    5 +-
 5 files changed, 156 insertions(+), 190 deletions(-)

diff --git a/opensm/include/opensm/osm_multicast.h b/opensm/include/opensm/osm_multicast.h
index 567a989..626c5af 100644
--- a/opensm/include/opensm/osm_multicast.h
+++ b/opensm/include/opensm/osm_multicast.h
@@ -206,13 +206,10 @@ typedef struct _osm_mgrp_port {
 typedef struct osm_mgrp {
 	cl_map_item_t map_item;
 	ib_net16_t mlid;
-	osm_mtree_node_t *p_root;
 	cl_qmap_t mcm_port_tbl;
 	ib_member_rec_t mcmember_rec;
 	boolean_t well_known;
 	boolean_t to_be_deleted;
-	uint32_t last_change_id;
-	uint32_t last_tree_id;
 	unsigned full_members;
 	cl_fmap_item_t mgid_item;
 	cl_list_item_t mgrp_item;
@@ -331,7 +328,8 @@ osm_mgrp_t *osm_mgrp_new(IN const ib_net16_t mlid);
 *
 * SYNOPSIS
 */
-void osm_mgrp_delete_group(IN osm_subn_t * p_subn, IN osm_mgrp_t * const p_mgrp);
+void osm_mgrp_delete_group(IN osm_subn_t * p_subn,
+			   IN osm_mgrp_t * const p_mgrp);
 /*
 * PARAMETERS
 *	p_mgrp
@@ -841,10 +839,10 @@ void osm_mgrp_holder_prepare_common_mgid(IN const ib_gid_t * const p_mgid,
 *
 * SYNOPSIS
 */
-static inline
-    struct osm_mgrp_holder *osm_get_mgrp_holder_by_mlid(osm_subn_t const
-							*p_subn,
-							ib_net16_t mlid)
+static inline struct osm_mgrp_holder *osm_get_mgrp_holder_by_mlid(osm_subn_t const
+								  *p_subn,
+								  ib_net16_t
+								  mlid)
 {
 	return p_subn->mgroup_holders[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
 }
diff --git a/opensm/include/opensm/osm_subnet.h b/opensm/include/opensm/osm_subnet.h
index 6713d4d..cafdd6b 100644
--- a/opensm/include/opensm/osm_subnet.h
+++ b/opensm/include/opensm/osm_subnet.h
@@ -508,7 +508,6 @@ typedef struct osm_subn {
 	boolean_t first_time_master_sweep;
 	boolean_t coming_out_of_standby;
 	unsigned need_update;
-	void *mgroups[IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 1];
 	void *mgroup_holders[IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 1];
 } osm_subn_t;
 /*
@@ -630,10 +629,6 @@ typedef struct osm_subn {
 *		This flag should be on during first non-master heavy
 *		(including pre-master discovery stage)
 *
-*	mgroups
-*		Array of pointers to all Multicast Group objects in the subnet.
-*		Indexed by MLID offset from base MLID.
-*
 *	mgroup_holders
 *		Array of pointers to all Multicast Group Holder objects in the subnet.
 *		Indexed by MLID offset from base MLID.
@@ -935,34 +930,6 @@ struct osm_port *osm_get_port_by_guid(IN osm_subn_t const *p_subn,
 *	osm_port_t
 *********/
 
-/****f* OpenSM: Subnet/osm_get_mgrp_by_mlid
-* NAME
-*	osm_get_mgrp_by_mlid
-*
-* DESCRIPTION
-*	The looks for the given multicast group in the subnet table by mlid.
-*	NOTE: this code is not thread safe. Need to grab the lock before
-*	calling it.
-*
-* SYNOPSIS
-*/
-static inline
-struct osm_mgrp *osm_get_mgrp_by_mlid(osm_subn_t const *p_subn, ib_net16_t mlid)
-{
-	return p_subn->mgroups[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
-}
-/*
-* PARAMETERS
-*	p_subn
-*		[in] Pointer to an osm_subn_t object
-*
-*	mlid
-*		[in] The multicast group mlid in network order
-*
-* RETURN VALUES
-*	The multicast group structure pointer if found. NULL otherwise.
-*********/
-
 /****f* OpenSM: Helper/osm_get_physp_by_mad_addr
 * NAME
 *	osm_get_physp_by_mad_addr
diff --git a/opensm/opensm/osm_mcast_mgr.c b/opensm/opensm/osm_mcast_mgr.c
index e16c2e7..1bc980c 100644
--- a/opensm/opensm/osm_mcast_mgr.c
+++ b/opensm/opensm/osm_mcast_mgr.c
@@ -55,6 +55,7 @@
 #include <opensm/osm_switch.h>
 #include <opensm/osm_helper.h>
 #include <opensm/osm_msgdef.h>
+#include <arpa/inet.h>
 
 /**********************************************************************
  **********************************************************************/
@@ -111,14 +112,15 @@ static void mcast_mgr_purge_tree_node(IN osm_mtree_node_t * p_mtn)
 
 /**********************************************************************
  **********************************************************************/
-static void mcast_mgr_purge_tree(osm_sm_t * sm, IN osm_mgrp_t * p_mgrp)
+static void mcast_mgr_purge_tree(osm_sm_t * sm,
+				 IN osm_mgrp_holder_t * p_mgrp_holder)
 {
 	OSM_LOG_ENTER(sm->p_log);
 
-	if (p_mgrp->p_root)
-		mcast_mgr_purge_tree_node(p_mgrp->p_root);
+	if (p_mgrp_holder->p_root)
+		mcast_mgr_purge_tree_node(p_mgrp_holder->p_root);
 
-	p_mgrp->p_root = NULL;
+	p_mgrp_holder->p_root = NULL;
 
 	OSM_LOG_EXIT(sm->p_log);
 }
@@ -126,41 +128,39 @@ static void mcast_mgr_purge_tree(osm_sm_t * sm, IN osm_mgrp_t * p_mgrp)
 /**********************************************************************
  **********************************************************************/
 static float osm_mcast_mgr_compute_avg_hops(osm_sm_t * sm,
-					    const osm_mgrp_t * p_mgrp,
+					    const osm_mgrp_holder_t *
+					    p_mgrp_holder,
 					    const osm_switch_t * p_sw)
 {
 	float avg_hops = 0;
 	uint32_t hops = 0;
 	uint32_t num_ports = 0;
 	const osm_port_t *p_port;
-	const osm_mcm_port_t *p_mcm_port;
-	const cl_qmap_t *p_mcm_tbl;
+	const osm_mgrp_port_t *p_holder_port;
 
 	OSM_LOG_ENTER(sm->p_log);
 
-	p_mcm_tbl = &p_mgrp->mcm_port_tbl;
-
 	/*
 	   For each member of the multicast group, compute the
 	   number of hops to its base LID.
 	 */
-	for (p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(p_mcm_tbl);
-	     p_mcm_port != (osm_mcm_port_t *) cl_qmap_end(p_mcm_tbl);
-	     p_mcm_port =
-	     (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item)) {
+	for (p_holder_port =
+	     (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+	     p_holder_port !=
+	     (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map);
+	     p_holder_port =
+	     (osm_mgrp_port_t *) cl_qmap_next(&p_holder_port->guid_item)) {
 		/*
 		   Acquire the port object for this port guid, then create
 		   the new worker object to build the list.
 		 */
 		p_port = osm_get_port_by_guid(sm->p_subn,
-					      ib_gid_get_guid(&p_mcm_port->
-							      port_gid));
+					      p_holder_port->port_guid);
 
 		if (!p_port) {
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A18: "
 				"No port object for port 0x%016" PRIx64 "\n",
-				cl_ntoh64(ib_gid_get_guid
-					  (&p_mcm_port->port_gid)));
+				cl_ntoh64(p_holder_port->port_guid));
 			continue;
 		}
 
@@ -185,40 +185,37 @@ static float osm_mcast_mgr_compute_avg_hops(osm_sm_t * sm,
  of the group HCAs
  **********************************************************************/
 static float osm_mcast_mgr_compute_max_hops(osm_sm_t * sm,
-					    const osm_mgrp_t * p_mgrp,
+					    const osm_mgrp_holder_t *
+					    p_mgrp_holder,
 					    const osm_switch_t * p_sw)
 {
 	uint32_t max_hops = 0;
 	uint32_t hops = 0;
 	const osm_port_t *p_port;
-	const osm_mcm_port_t *p_mcm_port;
-	const cl_qmap_t *p_mcm_tbl;
+	const osm_mgrp_port_t *p_mgrp_holder_port;
 
 	OSM_LOG_ENTER(sm->p_log);
 
-	p_mcm_tbl = &p_mgrp->mcm_port_tbl;
-
 	/*
 	   For each member of the multicast group, compute the
 	   number of hops to its base LID.
 	 */
-	for (p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(p_mcm_tbl);
-	     p_mcm_port != (osm_mcm_port_t *) cl_qmap_end(p_mcm_tbl);
-	     p_mcm_port =
-	     (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item)) {
+	for (p_mgrp_holder_port =
+	     (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+	     p_mgrp_holder_port !=
+	     (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map);
+	     p_mgrp_holder_port =
+	     (osm_mgrp_port_t *) cl_qmap_next(&p_mgrp_holder_port->guid_item)) {
 		/*
 		   Acquire the port object for this port guid, then create
 		   the new worker object to build the list.
 		 */
 		p_port = osm_get_port_by_guid(sm->p_subn,
-					      ib_gid_get_guid(&p_mcm_port->
-							      port_gid));
-
+					      p_mgrp_holder_port->port_guid);
 		if (!p_port) {
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A1A: "
 				"No port object for port 0x%016" PRIx64 "\n",
-				cl_ntoh64(ib_gid_get_guid
-					  (&p_mcm_port->port_gid)));
+				cl_ntoh64(p_mgrp_holder_port->port_guid));
 			continue;
 		}
 
@@ -244,15 +241,16 @@ static float osm_mcast_mgr_compute_max_hops(osm_sm_t * sm,
    of the multicast group.
 **********************************************************************/
 static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
-						   const osm_mgrp_t * p_mgrp)
+						   const osm_mgrp_holder_t *
+						   p_mgrp_holder)
 {
 	cl_qmap_t *p_sw_tbl;
-	const osm_switch_t *p_sw;
-	const osm_switch_t *p_best_sw = NULL;
+	osm_switch_t *p_sw;
+	osm_switch_t *p_best_sw = NULL;
 	float hops = 0;
 	float best_hops = 10000;	/* any big # will do */
 #ifdef OSM_VENDOR_INTF_ANAFA
-	boolean_t use_avg_hops = TRUE;	/* anafa2 - bug hca on switch *//* use max hops for root */
+	boolean_t use_avg_hops = TRUE;	/* anafa2 - bug hca on switch - use max hops for root */
 #else
 	boolean_t use_avg_hops = FALSE;	/* use max hops for root */
 #endif
@@ -260,8 +258,7 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
 	OSM_LOG_ENTER(sm->p_log);
 
 	p_sw_tbl = &sm->p_subn->sw_guid_tbl;
-
-	CL_ASSERT(!osm_mgrp_is_empty(p_mgrp));
+	CL_ASSERT(!osm_mgrp_holder_is_empty(p_mgrp_holder));
 
 	for (p_sw = (osm_switch_t *) cl_qmap_head(p_sw_tbl);
 	     p_sw != (osm_switch_t *) cl_qmap_end(p_sw_tbl);
@@ -270,9 +267,13 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
 			continue;
 
 		if (use_avg_hops)
-			hops = osm_mcast_mgr_compute_avg_hops(sm, p_mgrp, p_sw);
+			hops =
+			    osm_mcast_mgr_compute_avg_hops(sm, p_mgrp_holder,
+							   p_sw);
 		else
-			hops = osm_mcast_mgr_compute_max_hops(sm, p_mgrp, p_sw);
+			hops =
+			    osm_mcast_mgr_compute_max_hops(sm, p_mgrp_holder,
+							   p_sw);
 
 		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 			"Switch 0x%016" PRIx64 ", hops = %f\n",
@@ -301,7 +302,8 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
    This function returns the existing or optimal root swtich for the tree.
 **********************************************************************/
 static osm_switch_t *mcast_mgr_find_root_switch(osm_sm_t * sm,
-						const osm_mgrp_t * p_mgrp)
+						const osm_mgrp_holder_t *
+						p_mgrp_holder)
 {
 	const osm_switch_t *p_sw = NULL;
 
@@ -313,7 +315,7 @@ static osm_switch_t *mcast_mgr_find_root_switch(osm_sm_t * sm,
 	   the root will be always on the first switch attached to it.
 	   - Very bad ...
 	 */
-	p_sw = mcast_mgr_find_optimal_switch(sm, p_mgrp);
+	p_sw = mcast_mgr_find_optimal_switch(sm, p_mgrp_holder);
 
 	OSM_LOG_EXIT(sm->p_log);
 	return (osm_switch_t *) p_sw;
@@ -394,7 +396,8 @@ static osm_signal_t mcast_mgr_set_tbl(osm_sm_t * sm, IN osm_switch_t * p_sw)
   spanning tree that eminate from this switch.  On input, the p_list
   contains the group members that must be routed from this switch.
 **********************************************************************/
-static void mcast_mgr_subdivide(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
+static void mcast_mgr_subdivide(osm_sm_t * sm,
+				osm_mgrp_holder_t * p_mgrp_holder,
 				osm_switch_t * p_sw, cl_qlist_t * p_list,
 				cl_qlist_t * list_array, uint8_t array_size)
 {
@@ -405,7 +408,7 @@ static void mcast_mgr_subdivide(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
 
 	OSM_LOG_ENTER(sm->p_log);
 
-	mlid_ho = cl_ntoh16(osm_mgrp_get_mlid(p_mgrp));
+	mlid_ho = cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder));
 
 	/*
 	   For Multicast Groups, we want not to count on previous
@@ -495,7 +498,8 @@ static void mcast_mgr_purge_list(osm_sm_t * sm, cl_qlist_t * p_list)
 
   The function returns the newly created mtree node element.
 **********************************************************************/
-static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
+static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm,
+					  osm_mgrp_holder_t * p_mgrp_holder,
 					  osm_switch_t * p_sw,
 					  cl_qlist_t * p_list, uint8_t depth,
 					  uint8_t upstream_port,
@@ -521,7 +525,7 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
 
 	node_guid = osm_node_get_node_guid(p_sw->p_node);
 	node_guid_ho = cl_ntoh64(node_guid);
-	mlid_ho = cl_ntoh16(osm_mgrp_get_mlid(p_mgrp));
+	mlid_ho = cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder));
 
 	OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 		"Routing MLID 0x%X through switch 0x%" PRIx64
@@ -598,7 +602,8 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
 	for (i = 0; i < max_children; i++)
 		cl_qlist_init(&list_array[i]);
 
-	mcast_mgr_subdivide(sm, p_mgrp, p_sw, p_list, list_array, max_children);
+	mcast_mgr_subdivide(sm, p_mgrp_holder, p_sw, p_list, list_array,
+			    max_children);
 
 	p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw);
 
@@ -681,8 +686,9 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
 			CL_ASSERT(p_remote_physp);
 
 			p_mtn->child_array[i] =
-			    mcast_mgr_branch(sm, p_mgrp, p_remote_node->sw,
-					     p_port_list, depth,
+			    mcast_mgr_branch(sm, p_mgrp_holder,
+					     p_remote_node->sw, p_port_list,
+					     depth,
 					     osm_physp_get_port_num
 					     (p_remote_physp), p_max_depth);
 		} else {
@@ -717,11 +723,11 @@ Exit:
 /**********************************************************************
  **********************************************************************/
 static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
-						     osm_mgrp_t * p_mgrp)
+						     osm_mgrp_holder_t *
+						     p_mgrp_holder)
 {
-	const cl_qmap_t *p_mcm_tbl;
 	const osm_port_t *p_port;
-	const osm_mcm_port_t *p_mcm_port;
+	const osm_mgrp_port_t *p_mgrp_port;
 	uint32_t num_ports;
 	cl_qlist_t port_list;
 	osm_switch_t *p_sw;
@@ -740,14 +746,13 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
 	   on multicast forwarding table information if the user wants to
 	   preserve existing multicast routes.
 	 */
-	mcast_mgr_purge_tree(sm, p_mgrp);
+	mcast_mgr_purge_tree(sm, p_mgrp_holder);
 
-	p_mcm_tbl = &p_mgrp->mcm_port_tbl;
-	num_ports = cl_qmap_count(p_mcm_tbl);
+	num_ports = cl_qmap_count(&p_mgrp_holder->mgrp_port_map);
 	if (num_ports == 0) {
 		OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 			"MLID 0x%X has no members - nothing to do\n",
-			cl_ntoh16(osm_mgrp_get_mlid(p_mgrp)));
+			cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder)));
 		goto Exit;
 	}
 
@@ -767,11 +772,11 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
 	   Locate the switch around which to create the spanning
 	   tree for this multicast group.
 	 */
-	p_sw = mcast_mgr_find_root_switch(sm, p_mgrp);
+	p_sw = mcast_mgr_find_root_switch(sm, p_mgrp_holder);
 	if (p_sw == NULL) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A08: "
 			"Unable to locate a suitable switch for group 0x%X\n",
-			cl_ntoh16(osm_mgrp_get_mlid(p_mgrp)));
+			cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder)));
 		status = IB_ERROR;
 		goto Exit;
 	}
@@ -779,22 +784,22 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
 	/*
 	   Build the first "subset" containing all member ports.
 	 */
-	for (p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(p_mcm_tbl);
-	     p_mcm_port != (osm_mcm_port_t *) cl_qmap_end(p_mcm_tbl);
-	     p_mcm_port =
-	     (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item)) {
+	for (p_mgrp_port =
+	     (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+	     p_mgrp_port !=
+	     (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map);
+	     p_mgrp_port =
+	     (osm_mgrp_port_t *) cl_qmap_next(&p_mgrp_port->guid_item)) {
 		/*
 		   Acquire the port object for this port guid, then create
 		   the new worker object to build the list.
 		 */
-		p_port = osm_get_port_by_guid(sm->p_subn,
-					      ib_gid_get_guid(&p_mcm_port->
-							      port_gid));
+		p_port =
+		    osm_get_port_by_guid(sm->p_subn, p_mgrp_port->port_guid);
 		if (!p_port) {
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A09: "
 				"No port object for port 0x%016" PRIx64 "\n",
-				cl_ntoh64(ib_gid_get_guid
-					  (&p_mcm_port->port_gid)));
+				cl_ntoh64(p_mgrp_port->port_guid));
 			continue;
 		}
 
@@ -802,8 +807,7 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
 		if (p_wobj == NULL) {
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A10: "
 				"Insufficient memory to route port 0x%016"
-				PRIx64 "\n",
-				cl_ntoh64(osm_port_get_guid(p_port)));
+				PRIx64 "\n", cl_ntoh64(p_mgrp_port->port_guid));
 			continue;
 		}
 
@@ -811,12 +815,14 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
 	}
 
 	count = cl_qlist_count(&port_list);
-	p_mgrp->p_root = mcast_mgr_branch(sm, p_mgrp, p_sw, &port_list, 0, 0,
-					  &max_depth);
+	p_mgrp_holder->p_root =
+	    mcast_mgr_branch(sm, p_mgrp_holder, p_sw, &port_list, 0, 0,
+			     &max_depth);
 
 	OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 		"Configured MLID 0x%X for %u ports, max tree depth = %u\n",
-		cl_ntoh16(osm_mgrp_get_mlid(p_mgrp)), count, max_depth);
+		cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder)), count,
+		max_depth);
 
 Exit:
 	OSM_LOG_EXIT(sm->p_log);
@@ -1023,14 +1029,18 @@ Exit:
    lock must already be held on entry
 **********************************************************************/
 static ib_api_status_t osm_mcast_mgr_process_tree(osm_sm_t * sm,
-						  IN osm_mgrp_t * p_mgrp)
+						  IN osm_mgrp_holder_t *
+						  p_mgrp_holder)
 {
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net16_t mlid;
+	osm_mgrp_t *p_mgrp;
+	cl_fmap_item_t *p_fitem;
+	unsigned has_full_members = 0;
 
 	OSM_LOG_ENTER(sm->p_log);
 
-	mlid = osm_mgrp_get_mlid(p_mgrp);
+	mlid = osm_mgrp_holder_get_mlid(p_mgrp_holder);
 
 	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 		"Processing multicast group 0x%X\n", cl_ntoh16(mlid));
@@ -1051,10 +1061,18 @@ static ib_api_status_t osm_mcast_mgr_process_tree(osm_sm_t * sm,
 	 */
 	mcast_mgr_clear(sm, cl_ntoh16(mlid));
 
-	if (!p_mgrp->full_members)
+	p_fitem = cl_fmap_head(&p_mgrp_holder->mgrp_map);
+	while (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
+		p_mgrp = (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
+						      mgid_item);
+		if (0 != (has_full_members = p_mgrp->full_members))
+			break;
+		p_fitem = cl_fmap_next(p_fitem);
+	}
+	if (!has_full_members)
 		goto Exit;
 
-	status = mcast_mgr_build_spanning_tree(sm, p_mgrp);
+	status = mcast_mgr_build_spanning_tree(sm, p_mgrp_holder);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A17: "
 			"Unable to create spanning tree (%s)\n",
@@ -1068,33 +1086,62 @@ Exit:
 }
 
 /**********************************************************************
- Process the entire group.
+ Process the entire group holder.
  NOTE : The lock should be held externally!
  **********************************************************************/
 static ib_api_status_t mcast_mgr_process_mgrp(osm_sm_t * sm,
-					      IN osm_mgrp_t * p_mgrp)
+					      IN osm_mgrp_holder_t *
+					      p_mgrp_holder)
 {
 	ib_api_status_t status;
+	osm_mgrp_t *p_mgrp;
+	cl_fmap_item_t *p_fitem;
+	ib_net16_t mlid;
+	char gid_str[INET6_ADDRSTRLEN];
 
 	OSM_LOG_ENTER(sm->p_log);
 
-	status = osm_mcast_mgr_process_tree(sm, p_mgrp);
+	status = osm_mcast_mgr_process_tree(sm, p_mgrp_holder);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A19: "
 			"Unable to create spanning tree (%s)\n",
 			ib_get_err_str(status));
 		goto Exit;
 	}
-	p_mgrp->last_tree_id = p_mgrp->last_change_id;
-
-	/* remove MCGRP if it is marked for deletion */
-	if (p_mgrp->to_be_deleted) {
+	p_mgrp_holder->last_tree_id = p_mgrp_holder->last_change_id;
+
+	p_fitem = cl_fmap_head(&p_mgrp_holder->mgrp_map);
+	while (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
+		p_mgrp = (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
+						      mgid_item);
+		mlid = p_mgrp->mlid;
+		if (osm_is_debug()) {
+			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+				"holder mlid 0x%X has mgrp mgid = %s\n",
+				cl_ntoh16(p_mgrp_holder->mlid),
+				inet_ntop(AF_INET6,
+					  p_mgrp->mcmember_rec.mgid.raw,
+					  gid_str, sizeof(gid_str)));
+		}
+		/* remove MCGRP if it is marked for deletion */
+		if (p_mgrp->to_be_deleted) {
+			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+				"Destroying mgrp  %s with lid:0x%x\n",
+				inet_ntop(AF_INET6,
+					  p_mgrp->mcmember_rec.mgid.raw,
+					  gid_str, sizeof(gid_str)),
+				cl_ntoh16(p_mgrp->mlid));
+			osm_mgrp_delete_group(sm->p_subn, p_mgrp);
+			p_fitem = cl_fmap_head(&p_mgrp_holder->mgrp_map);
+		} else
+			p_fitem = cl_fmap_next(p_fitem);
+	}
+	if (0 == cl_fmap_count(&p_mgrp_holder->mgrp_map)) {
+		/* no more groups on this mlid */
 		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
-			"Destroying mgrp with lid:0x%x\n",
-			cl_ntoh16(p_mgrp->mlid));
-		sm->p_subn->mgroups[cl_ntoh16(p_mgrp->mlid) -
-				    IB_LID_MCAST_START_HO] = NULL;
-		osm_mgrp_delete(p_mgrp);
+			"Destroying mgrp_holder with lid:0x%x\n",
+			cl_ntoh16(p_mgrp_holder->mlid));
+		osm_mgrp_holder_delete(sm->p_subn, p_mgrp_holder->mlid);
 	}
 
 Exit:
@@ -1110,7 +1157,7 @@ osm_signal_t osm_mcast_mgr_process(osm_sm_t * sm)
 	osm_switch_t *p_sw;
 	cl_qmap_t *p_sw_tbl;
 	cl_qlist_t *p_list = &sm->mgrp_list;
-	osm_mgrp_t *p_mgrp;
+	osm_mgrp_holder_t *p_mgrp_holder;
 	boolean_t pending_transactions = FALSE;
 	int i;
 
@@ -1132,9 +1179,10 @@ osm_signal_t osm_mcast_mgr_process(osm_sm_t * sm)
 		   of the subnet. Not due to a specific multicast request.
 		   So the request type is subnet_change and the port guid is 0.
 		 */
-		p_mgrp = sm->p_subn->mgroups[i];
-		if (p_mgrp)
-			mcast_mgr_process_mgrp(sm, p_mgrp);
+		p_mgrp_holder = sm->p_subn->mgroup_holders[i];
+		if (p_mgrp_holder) {
+			mcast_mgr_process_mgrp(sm, p_mgrp_holder);
+		}
 	}
 
 	/*
@@ -1172,7 +1220,7 @@ osm_signal_t osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
 	cl_qlist_t *p_list = &sm->mgrp_list;
 	osm_switch_t *p_sw;
 	cl_qmap_t *p_sw_tbl;
-	osm_mgrp_t *p_mgrp;
+	osm_mgrp_holder_t *p_mgrp_holder;
 	ib_net16_t mlid;
 	osm_signal_t ret, signal = OSM_SIGNAL_DONE;
 	osm_mcast_mgr_ctxt_t *ctx;
@@ -1193,24 +1241,25 @@ osm_signal_t osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
 
 		/* since we delayed the execution we prefer to pass the
 		   mlid as the mgrp identifier and then find it or abort */
-		p_mgrp = osm_get_mgrp_by_mlid(sm->p_subn, mlid);
-		if (!p_mgrp)
+		p_mgrp_holder = osm_get_mgrp_holder_by_mlid(sm->p_subn, mlid);
+		if (!p_mgrp_holder)
 			continue;
 
 		/* if there was no change from the last time
 		 * we processed the group we can skip doing anything
 		 */
-		if (p_mgrp->last_change_id == p_mgrp->last_tree_id) {
+		if (p_mgrp_holder->last_change_id ==
+		    p_mgrp_holder->last_tree_id) {
 			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
-				"Skip processing mgrp with lid:0x%X change id:%u\n",
-				cl_ntoh16(mlid), p_mgrp->last_change_id);
+				"Skip processing p_mgrp_holder with lid:0x%X change id:%u\n",
+				cl_ntoh16(mlid), p_mgrp_holder->last_change_id);
 			continue;
 		}
 
 		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 			"Processing mgrp with lid:0x%X change id:%u\n",
-			cl_ntoh16(mlid), p_mgrp->last_change_id);
-		mcast_mgr_process_mgrp(sm, p_mgrp);
+			cl_ntoh16(mlid), p_mgrp_holder->last_change_id);
+		mcast_mgr_process_mgrp(sm, p_mgrp_holder);
 	}
 
 	/*
diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
index e2e588c..e687ca8 100644
--- a/opensm/opensm/osm_multicast.c
+++ b/opensm/opensm/osm_multicast.c
@@ -54,28 +54,6 @@
 
 /**********************************************************************
  **********************************************************************/
-void osm_mgrp_delete(IN osm_mgrp_t * p_mgrp)
-{
-	osm_mcm_port_t *p_mcm_port;
-	osm_mcm_port_t *p_next_mcm_port;
-
-	CL_ASSERT(p_mgrp);
-
-	p_next_mcm_port =
-	    (osm_mcm_port_t *) cl_qmap_head(&p_mgrp->mcm_port_tbl);
-	while (p_next_mcm_port !=
-	       (osm_mcm_port_t *) cl_qmap_end(&p_mgrp->mcm_port_tbl)) {
-		p_mcm_port = p_next_mcm_port;
-		p_next_mcm_port =
-		    (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item);
-		osm_mcm_port_delete(p_mcm_port);
-	}
-	/* destroy the mtree_node structure */
-	osm_mtree_destroy(p_mgrp->p_root);
-
-	free(p_mgrp);
-}
-
 void osm_mgrp_delete_group(IN osm_subn_t * p_subn, IN osm_mgrp_t * p_mgrp)
 {
 	osm_mcm_port_t *p_mcm_port;
@@ -114,10 +92,7 @@ osm_mgrp_t *osm_mgrp_new(IN const ib_net16_t mlid)
 	memset(p_mgrp, 0, sizeof(*p_mgrp));
 	cl_qmap_init(&p_mgrp->mcm_port_tbl);
 	p_mgrp->mlid = mlid;
-	p_mgrp->last_change_id = 0;
-	p_mgrp->last_tree_id = 0;
 	p_mgrp->to_be_deleted = FALSE;
-
 	return p_mgrp;
 }
 
@@ -195,11 +170,7 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t * subn, osm_log_t * log,
 		p_mcm_port->scope_state =
 		    ib_member_set_scope_state(prev_scope,
 					      prev_join_state | join_state);
-	} else {
-		/* track the fact we modified the group ports */
-		p_mgrp->last_change_id++;
 	}
-
 	if ((join_state & IB_JOIN_STATE_FULL) &&
 	    !(prev_join_state & IB_JOIN_STATE_FULL) &&
 	    (++p_mgrp->full_members == 1)) {
@@ -239,8 +210,6 @@ int osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
 		OSM_LOG(log, OSM_LOG_DEBUG, "removing port 0x%" PRIx64 "\n",
 			cl_ntoh64(mcm->port_gid.unicast.interface_id));
 		osm_mcm_port_delete(mcm);
-		/* track the fact we modified the group */
-		mgrp->last_change_id++;
 		ret = 1;
 	}
 
@@ -313,22 +282,6 @@ static void mgrp_apply_func_sub(const osm_mgrp_t * p_mgrp,
 
 /**********************************************************************
  **********************************************************************/
-void osm_mgrp_apply_func(const osm_mgrp_t * p_mgrp, osm_mgrp_func_t p_func,
-			 void *context)
-{
-	osm_mtree_node_t *p_mtn;
-
-	CL_ASSERT(p_mgrp);
-	CL_ASSERT(p_func);
-
-	p_mtn = p_mgrp->p_root;
-
-	if (p_mtn)
-		mgrp_apply_func_sub(p_mgrp, p_mtn, p_func, context);
-}
-
-/**********************************************************************
- **********************************************************************/
 #define PREFIX_MASK_IP CL_HTON64(0xff10ffff0000ffffULL)
 #define PREFIX_SIGNATURE_IPV4 CL_HTON64(0xff10401b00000000ULL)
 #define INTERFACE_ID_IPV4            CL_HTON64(0x0000000fffffffffULL)
diff --git a/opensm/opensm/osm_sm.c b/opensm/opensm/osm_sm.c
index 459e2cc..d74b4df 100644
--- a/opensm/opensm/osm_sm.c
+++ b/opensm/opensm/osm_sm.c
@@ -509,15 +509,14 @@ ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
 			size_t gr_count =
 			    cl_fmap_count(&p_mgrp_holder->mgrp_map);
 			OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
-				"mlid 0x%X has  %d mgroups\n", cl_ntoh16(mlid),
+				"mlid 0x%X has  %lu mgroups\n", cl_ntoh16(mlid),
 				gr_count);
 			if (gr_count) {
 				p_fitem =
 				    cl_fmap_head(&p_mgrp_holder->mgrp_map);
 				while (p_fitem !=
 				       cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
-					p_mgrp =
-					    (osm_mgrp_t *)
+					p_mgrp = (osm_mgrp_t *)
 					    PARENT_STRUCT(p_fitem, osm_mgrp_t,
 							  mgid_item);
 					OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
-- 
1.5.5




More information about the general mailing list