[ofa-general] [PATCH 2/2 v4] opensm: Compression of multicast group according to pkey

Slava Strebkov slavas at Voltaire.COM
Tue Sep 29 06:54:12 PDT 2009


Additional data structure added:
1. Map of all partition keys opened in the fabric.
2. Map of all multicast group boxes shared same pkey.
MLID assignment for multicast groups works in a usual manner,
allocating free entry for newly created group.
Proposed compression algorithm starts working when there are no more
free entries in the mlid array. List of MLIDs for new multicast group
will be chosen from the pkey indexed map according to the requested
pkey. MLID which shares minimum number of ports will be given to newly
created multicast group.

Signed-off-by: Slava Strebkov <slavas at voltaire.com>
---
 opensm/include/opensm/osm_multicast.h  |  135 ++++++++++++++++++++++++++++++++
 opensm/include/opensm/osm_subnet.h     |   36 +++++++++
 opensm/opensm/osm_multicast.c          |  103 ++++++++++++++++++++++++
 opensm/opensm/osm_sa_mcmember_record.c |   28 ++++---
 opensm/opensm/osm_subnet.c             |    8 ++
 5 files changed, 299 insertions(+), 11 deletions(-)

diff --git a/opensm/include/opensm/osm_multicast.h b/opensm/include/opensm/osm_multicast.h
index d4daf4b..1ced651 100644
--- a/opensm/include/opensm/osm_multicast.h
+++ b/opensm/include/opensm/osm_multicast.h
@@ -148,6 +148,7 @@ typedef struct osm_mgrp_box {
 	cl_qlist_t mgrp_list;
 	ib_net16_t mlid;
 	osm_mtree_node_t *p_root;
+	cl_map_item_t mlid_item;
 } osm_mgrp_box_t;
 /*
 * FIELDS
@@ -167,6 +168,9 @@ typedef struct osm_mgrp_box {
 *		for this multicast group.  The nodes of the tree represent
 *		switches.  Member ports are not represented in the tree.
 *
+*	mlid_item
+*		list item in list of boxes shared same pkey.
+*
 * SEE ALSO
 *********/
 /****s* OpenSM: Multicast group Port /osm_mgrp_port_t
@@ -498,5 +502,136 @@ void osm_mgrp_box_delete(IN osm_subn_t * p_subn,
 * SEE ALSO
 *
 *********/
+
+/****f* OpenSM: Subnet/osm_mlid_pkey_delete
+* NAME
+*	osm_mlid_pkey_delete
+*
+* DESCRIPTION
+*	Frees the objects.
+*
+* SYNOPSIS
+*/
+void osm_mlid_pkey_delete(osm_mlid_pkey_t *p_mlid_pkey);
+/*
+* PARAMETERS
+*	p_mlid_pkey
+*		[in] Pointer to an osm_mlid_pkey_t object
+*
+* RETURN VALUES
+*	None.
+*
+* NOTES
+*
+* SEE ALSO
+*	osm_mlid_pkey_new
+*********/
+
+/****f* OpenSM: Subnet/osm_mlid_pkey_new
+* NAME
+*	osm_mlid_pkey_new
+*
+* DESCRIPTION
+*	Creates new object of osm_mlid_pkey_t.
+*
+* SYNOPSIS
+*/
+osm_mlid_pkey_t *osm_mlid_pkey_new(IN ib_net16_t pkey);
+/*
+* PARAMETERS
+*	pkey
+*		[in] Partition key for the object
+*
+* RETURN VALUES
+*	Pointer to osm_mlid_pkey_t, or NULL.
+*
+* SEE ALSO
+*	osm_mlid_pkey_delete
+*********/
+
+/****f* OpenSM: Subnet/osm_mlid_pkey_add_box
+* NAME
+*	osm_mlid_pkey_add_box
+*
+* DESCRIPTION
+*	Adds osm_mgrp_box_t object to map
+*
+* SYNOPSIS
+*/
+void osm_mlid_pkey_add_box(osm_mgrp_box_t *p_mgrp_box,
+				ib_net16_t pkey, osm_subn_t *p_subn);
+/*
+* PARAMETERS
+*	p_mgrp_box
+*		[in] Pointer to osm_mgrp_box_t
+*
+*	pkey
+*		[in] Partition key for the object
+*
+*	p_subn
+*		[in] Pointer to an osm_subn_t object
+*
+* RETURN VALUES
+*	None.
+*
+* SEE ALSO
+*	osm_mlid_pkey_remove_box
+*********/
+
+/****f* OpenSM: Subnet/osm_mlid_pkey_remove_box
+* NAME
+*	osm_mlid_pkey_remove_box
+*
+* DESCRIPTION
+*	removes osm_mgrp_box_t object from map
+*
+* SYNOPSIS
+*/
+void osm_mlid_pkey_remove_box(osm_mgrp_box_t *p_mgrp_box,
+			ib_net16_t pkey, osm_subn_t  *p_subn);
+/*
+* PARAMETERS
+*	p_mgrp_box
+*		[in] Pointer to osm_mgrp_box_t
+*
+*	pkey
+*		[in] Partition key for the object
+*
+*	p_subn
+*		[in] Pointer to an osm_subn_t object
+*
+* RETURN VALUES
+*	None.
+*
+* SEE ALSO
+*	osm_mlid_pkey_add_box
+*********/
+
+/****f* OpenSM: Subnet/osm_mlid_pkey_get_existed_mlid
+* NAME
+*	osm_mlid_pkey_get_existed_mlid
+*
+* DESCRIPTION
+*	return used mlid  with miminum ports, matched by pkey
+*
+* SYNOPSIS
+*/
+ib_net16_t osm_mlid_pkey_get_existed_mlid(IN osm_subn_t *p_subn, IN
+						ib_net16_t pkey);
+/*
+* PARAMETERS
+*
+*	p_subn
+*		[in] Pointer to an osm_subn_t object
+*
+*	pkey
+*		[in] Partition key for the object
+*
+* RETURN VALUES
+*	matched mlid or 0 if not found
+*
+* SEE ALSO
+*	osm_mlid_pkey_add_box
+*********/
 END_C_DECLS
 #endif				/* _OSM_MULTICAST_H_ */
diff --git a/opensm/include/opensm/osm_subnet.h b/opensm/include/opensm/osm_subnet.h
index fe4695f..d6ed9da 100644
--- a/opensm/include/opensm/osm_subnet.h
+++ b/opensm/include/opensm/osm_subnet.h
@@ -129,6 +129,37 @@ typedef struct osm_qos_options {
 *
 *********/
 
+/****s* OpenSM: Subnet/osm_mlid_pkey_t
+* NAME
+*	osm_mlid_pkey_t
+*
+* DESCRIPTION
+*	Structure combines all MLIDs opened on same pkey value.
+*	Used for mgid to mlid compresion
+*
+* SYNOPSIS
+*/
+typedef struct osm_mlid_pkey {
+	cl_map_item_t pkey_item;
+	ib_net16_t pkey;
+	cl_qmap_t mlid_box_map;
+} osm_mlid_pkey_t;
+/*
+* FIELDS
+*	pkey_item
+*		Map Item for qmap linkage.  Must be first element!!
+*		Indexed by pkey.
+*
+*	pkey
+*		Partition key (P_Key) for multicast group(s).
+*
+*	mlid_box_map
+*		Map of osm_mgrp_box_t objects. Indexed by mlid
+*
+* SEE ALSO
+*	osm_mgrp_box_t
+*********/
+
 /****s* OpenSM: Subnet/osm_subn_opt_t
 * NAME
 *	osm_subn_opt_t
@@ -515,6 +546,7 @@ typedef struct osm_subn {
 	unsigned need_update;
 	cl_fmap_t mgrp_mgid_tbl;
 	void *mboxes[IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 1];
+	cl_qmap_t mlid_pkey_tbl;
 } osm_subn_t;
 /*
 * FIELDS
@@ -639,6 +671,10 @@ typedef struct osm_subn {
 *		Array of pointers to all Multicast Group Box objects in the subnet.
 *		Indexed by MLID offset from base MLID.
 *
+*	mlid_pkey_tbl
+*		Map of osm_pkey_mlid_t objects. Arranged by mgrp pkey value.
+*		Contains MLIDs for mgroups with same pkey.
+*
 * SEE ALSO
 *	Subnet object
 *********/
diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
index 01c90d8..7e25b10 100644
--- a/opensm/opensm/osm_multicast.c
+++ b/opensm/opensm/osm_multicast.c
@@ -386,3 +386,106 @@ void osm_mgrp_box_delete(IN osm_subn_t *p_subn, ib_net16_t mlid)
 	p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = NULL;
 	free(p_mgrp_box);
 }
+
+/**********************************************************************
+**********************************************************************/
+void osm_mlid_pkey_delete(osm_mlid_pkey_t *p_mlid_pkey)
+{
+	cl_qmap_remove_all(&p_mlid_pkey->mlid_box_map);
+	free(p_mlid_pkey);
+}
+
+/**********************************************************************
+**********************************************************************/
+osm_mlid_pkey_t *osm_mlid_pkey_new(ib_net16_t pkey)
+{
+	osm_mlid_pkey_t *p_mlid_pkey = calloc(1,sizeof(osm_mlid_pkey_t));
+	if (!p_mlid_pkey) {
+		return NULL;
+	}
+	cl_qmap_init(&p_mlid_pkey->mlid_box_map);
+	p_mlid_pkey->pkey = pkey;
+	return p_mlid_pkey;
+}
+
+/**********************************************************************
+**********************************************************************/
+void osm_mlid_pkey_add_box(osm_mgrp_box_t *p_mgrp_box,
+				ib_net16_t pkey,  osm_subn_t  *p_subn)
+{
+	osm_mlid_pkey_t *p_mlid_pkey = (osm_mlid_pkey_t*)
+		cl_qmap_get(&p_subn->mlid_pkey_tbl,0x7fff & cl_ntoh16(pkey));
+	if (p_mlid_pkey != (osm_mlid_pkey_t*)cl_qmap_end(&p_subn->mlid_pkey_tbl)) {
+	cl_qmap_insert(&p_mlid_pkey->mlid_box_map, p_mgrp_box->mlid,
+		&p_mgrp_box->mlid_item);
+	}
+	else {
+		p_mlid_pkey = osm_mlid_pkey_new(pkey);
+		if (p_mlid_pkey) {
+			cl_qmap_insert(&p_mlid_pkey->mlid_box_map, p_mgrp_box->mlid,
+			&p_mgrp_box->mlid_item);
+			cl_qmap_insert(&p_subn->mlid_pkey_tbl, 0x7fff & cl_ntoh16(pkey),
+				&p_mlid_pkey->pkey_item);
+		}
+	}
+}
+
+/**********************************************************************
+**********************************************************************/
+void osm_mlid_pkey_remove_box(osm_mgrp_box_t *p_mgrp_box,
+			ib_net16_t pkey, osm_subn_t  *p_subn)
+{
+	osm_mlid_pkey_t *p_mlid_pkey = (osm_mlid_pkey_t*)
+		cl_qmap_get(&p_subn->mlid_pkey_tbl, 0x7fff & cl_ntoh16(pkey));
+	if (p_mlid_pkey != (osm_mlid_pkey_t*)cl_qmap_end(&p_subn->mlid_pkey_tbl)) {
+		cl_qmap_remove_item(&p_mlid_pkey->mlid_box_map, &p_mgrp_box->mlid_item);
+		if (!cl_qmap_count(&p_mlid_pkey->mlid_box_map)) {
+			/* no more groups with given pkey exist */
+			osm_mlid_pkey_delete(p_mlid_pkey);
+		}
+	}
+}
+
+/**********************************************************************
+**********************************************************************/
+static ib_net16_t osm_mlid_pkey_get_mlid(IN osm_mlid_pkey_t *p_mlid_pkey)
+{
+	cl_map_item_t *p_item;
+	osm_mgrp_box_t *p_mgrp_box;
+	osm_mgrp_box_t *p_matched_box = NULL;
+	size_t port_count = 0;
+	for (p_item = cl_qmap_head(&p_mlid_pkey->mlid_box_map);
+		p_item != cl_qmap_end(&p_mlid_pkey->mlid_box_map);
+		p_item = cl_qmap_next(p_item)) {
+			p_mgrp_box = (osm_mgrp_box_t*)
+				PARENT_STRUCT(p_item, osm_mgrp_box_t,mlid_item);
+			if (!port_count) {
+				/* init p_matched_holder and count */
+				port_count = cl_qmap_count(&p_mgrp_box->mgrp_port_map);
+				p_matched_box = p_mgrp_box;
+			}
+			else {
+				if (port_count > cl_qmap_count(&p_mgrp_box->mgrp_port_map)) {
+					port_count = cl_qmap_count(&p_mgrp_box->mgrp_port_map);
+					p_matched_box = p_mgrp_box;
+				}
+			}
+	}
+	if (p_matched_box) {
+		return p_matched_box->mlid;
+	}
+	return 0;
+}
+
+/**********************************************************************
+**********************************************************************/
+ib_net16_t osm_mlid_pkey_get_existed_mlid(IN osm_subn_t  *p_subn, IN ib_net16_t pkey)
+{
+	osm_mlid_pkey_t *p_mlid_pkey =
+		(osm_mlid_pkey_t*)cl_qmap_get(&p_subn->mlid_pkey_tbl, 0x7fff & cl_ntoh16(pkey));
+		if (p_mlid_pkey != (osm_mlid_pkey_t*)cl_qmap_end(&p_subn->mlid_pkey_tbl)) {
+			/* found obect with mgroups matched requested pkey */
+			return osm_mlid_pkey_get_mlid(p_mlid_pkey);
+		}
+	return 0;
+}
diff --git a/opensm/opensm/osm_sa_mcmember_record.c b/opensm/opensm/osm_sa_mcmember_record.c
index b39f986..fad8248 100644
--- a/opensm/opensm/osm_sa_mcmember_record.c
+++ b/opensm/opensm/osm_sa_mcmember_record.c
@@ -730,13 +730,14 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
 					     IN const osm_physp_t * p_physp,
 					     OUT osm_mgrp_t ** pp_mgrp)
 {
-	ib_net16_t mlid,existed_mlid;
+	ib_net16_t mlid;
 	unsigned zero_mgid, i;
 	uint8_t scope;
 	ib_gid_t *p_mgid;
 	osm_mgrp_box_t *p_mgrp_box;
 	ib_api_status_t status = IB_SUCCESS;
 	ib_member_rec_t mcm_rec = *p_recvd_mcmember_rec;	/* copy for modifications */
+	boolean_t new_mlid = TRUE;
 
 	OSM_LOG_ENTER(sa->p_log);
 
@@ -754,15 +755,22 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
 	 */
 	mlid = get_new_mlid(sa, mcm_rec.mlid);
 	if (mlid == 0) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B19: "
-			"get_new_mlid failed request mlid 0x%04x\n",
-			cl_ntoh16(mcm_rec.mlid));
-		status = IB_SA_MAD_STATUS_NO_RESOURCES;
-		goto Exit;
+		/* try to add mcgroup to existed mlid */
+		mlid = osm_mlid_pkey_get_existed_mlid(sa->p_subn, mcm_rec.pkey);
+		if (mlid ==  0) {
+			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B19: "
+				"get_new_mlid failed request mlid 0x%04x\n",
+				cl_ntoh16(mcm_rec.mlid));
+			status = IB_SA_MAD_STATUS_NO_RESOURCES;
+			goto Exit;
+		}
+		new_mlid = FALSE;
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+			"Found existed mlid 0x%X\n", cl_ntoh16(mlid));
 	}
 
 	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-		"Obtained new mlid 0x%X\n", cl_ntoh16(mlid));
+		"Obtained mlid 0x%X\n", cl_ntoh16(mlid));
 
 	/* we need to create the new MGID if it was not defined */
 	if (zero_mgid) {
@@ -812,10 +820,6 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
 		goto Exit;
 	}
 
-	/* check if there is mgrp_box matched to requested mgid */
-	if (0 != (existed_mlid = osm_mgrp_box_get_mlid_by_mgid(sa->p_subn, p_mgid))) {
-		mlid = existed_mlid;
-	}
 	/* create a new MC Group */
 	*pp_mgrp = osm_mgrp_new(mlid);
 	if (*pp_mgrp == NULL) {
@@ -859,6 +863,8 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
 	cl_fmap_insert(&sa->p_subn->mgrp_mgid_tbl,
 		       &(*pp_mgrp)->mcmember_rec.mgid, &(*pp_mgrp)->map_item);
 	sa->p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = p_mgrp_box;
+	if (new_mlid)
+		osm_mlid_pkey_add_box(p_mgrp_box,(*pp_mgrp)->mcmember_rec.pkey, sa->p_subn);
 	cl_qlist_insert_tail(&p_mgrp_box->mgrp_list, &(*pp_mgrp)->box_item);
 Exit:
 	OSM_LOG_EXIT(sa->p_log);
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index 61d766a..02989fa 100644
--- a/opensm/opensm/osm_subnet.c
+++ b/opensm/opensm/osm_subnet.c
@@ -416,6 +416,7 @@ void osm_subn_construct(IN osm_subn_t * const p_subn)
 	cl_qmap_init(&p_subn->rtr_guid_tbl);
 	cl_qmap_init(&p_subn->prtn_pkey_tbl);
 	cl_fmap_init(&p_subn->mgrp_mgid_tbl, compar_mgids);
+	cl_qmap_init(&p_subn->mlid_pkey_tbl);
 }
 
 /**********************************************************************
@@ -431,6 +432,7 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
 	osm_mgrp_t *p_mgrp;
 	osm_infr_t *p_infr, *p_next_infr;
 	osm_mgrp_box_t *p_mgrp_box;
+	osm_mlid_pkey_t *p_mlid_pkey;
 
 	/* it might be a good idea to de-allocate all known objects */
 	p_next_node = (osm_node_t *) cl_qmap_head(&p_subn->node_guid_tbl);
@@ -472,6 +474,12 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
 		osm_prtn_delete(&p_prtn);
 	}
 
+	p_mlid_pkey = (osm_mlid_pkey_t*)cl_qmap_head(&p_subn->mlid_pkey_tbl);
+	while (p_mlid_pkey != (osm_mlid_pkey_t*)cl_qmap_end(&p_subn->mlid_pkey_tbl)) {
+		cl_qmap_remove_item(&p_subn->mlid_pkey_tbl, (cl_map_item_t*)p_mlid_pkey);
+		osm_mlid_pkey_delete(p_mlid_pkey);
+		p_mlid_pkey = (osm_mlid_pkey_t*)cl_qmap_head(&p_subn->mlid_pkey_tbl);
+	}
 
 	for (i = 0; i <= p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO;
 	     i++) {
-- 
1.6.3.3




More information about the general mailing list