[ofa-general] [PATCH] opensm: improve multicast re-routing requests processing

Sasha Khapyorsky sashak at voltaire.com
Sun Sep 6 10:39:00 PDT 2009


When we have two or more changes in a same multicast group multiple
multicast rerouting requests will be created and processed. To prevent
this we will use array of requests indexed by mlid value minus
IB_LID_MCAST_START_HO and for each multicast group change we will just
mark that specific mlid requires re-routing and "duplicated" requests
will be merged there.

Also in this way we will be able to process multicast group routing
entries deletion for already removed groups by just knowing its MLID
and not using its content - this will let us to not delay mutlicast
groups deletion ('to_be_deleted' flag) and will simplify many multicast
related code flows.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 opensm/include/opensm/osm_sm.h |    4 +-
 opensm/opensm/osm_mcast_mgr.c  |   27 +++++++++------------
 opensm/opensm/osm_sm.c         |   49 +++++++++++++---------------------------
 3 files changed, 30 insertions(+), 50 deletions(-)

diff --git a/opensm/include/opensm/osm_sm.h b/opensm/include/opensm/osm_sm.h
index 0914a95..986143a 100644
--- a/opensm/include/opensm/osm_sm.h
+++ b/opensm/include/opensm/osm_sm.h
@@ -126,8 +126,8 @@ typedef struct osm_sm {
 	cl_dispatcher_t *p_disp;
 	cl_plock_t *p_lock;
 	atomic32_t sm_trans_id;
-	cl_spinlock_t mgrp_lock;
-	cl_qlist_t mgrp_list;
+	unsigned mlids_req_max;
+	uint8_t *mlids_req;
 	osm_sm_mad_ctrl_t mad_ctrl;
 	osm_lid_mgr_t lid_mgr;
 	osm_ucast_mgr_t ucast_mgr;
diff --git a/opensm/opensm/osm_mcast_mgr.c b/opensm/opensm/osm_mcast_mgr.c
index d7c5ce1..dd504ef 100644
--- a/opensm/opensm/osm_mcast_mgr.c
+++ b/opensm/opensm/osm_mcast_mgr.c
@@ -1116,7 +1116,6 @@ static int mcast_mgr_set_mftables(osm_sm_t * sm)
 int osm_mcast_mgr_process(osm_sm_t * sm)
 {
 	cl_qmap_t *p_sw_tbl;
-	cl_qlist_t *p_list = &sm->mgrp_list;
 	osm_mgrp_t *p_mgrp;
 	int i, ret = 0;
 
@@ -1150,16 +1149,14 @@ int osm_mcast_mgr_process(osm_sm_t * sm)
 			mcast_mgr_process_mgrp(sm, p_mgrp);
 	}
 
+	memset(sm->mlids_req, 0, sm->mlids_req_max);
+	sm->mlids_req_max = 0;
+
 	/*
 	   Walk the switches and download the tables for each.
 	 */
 	ret = mcast_mgr_set_mftables(sm);
 
-	while (!cl_is_qlist_empty(p_list)) {
-		cl_list_item_t *p = cl_qlist_remove_head(p_list);
-		free(p);
-	}
-
 exit:
 	CL_PLOCK_RELEASE(sm->p_lock);
 
@@ -1174,11 +1171,10 @@ exit:
  **********************************************************************/
 int osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
 {
-	cl_qlist_t *p_list = &sm->mgrp_list;
 	osm_mgrp_t *p_mgrp;
 	ib_net16_t mlid;
-	osm_mcast_mgr_ctxt_t *ctx;
 	int ret = 0;
+	unsigned i;
 
 	OSM_LOG_ENTER(sm->p_log);
 
@@ -1192,14 +1188,12 @@ int osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
 		goto exit;
 	}
 
-	while (!cl_is_qlist_empty(p_list)) {
-		ctx = (osm_mcast_mgr_ctxt_t *) cl_qlist_remove_head(p_list);
-
-		/* nice copy no warning on size diff */
-		memcpy(&mlid, &ctx->mlid, sizeof(mlid));
+	for (i = 0; i <= sm->mlids_req_max; i++) {
+		if (!sm->mlids_req[i])
+			continue;
+		sm->mlids_req[i] = 0;
 
-		/* we can destroy the context now */
-		free(ctx);
+		mlid = cl_hton16(i + IB_LID_MCAST_START_HO);
 
 		/* since we delayed the execution we prefer to pass the
 		   mlid as the mgrp identifier and then find it or abort */
@@ -1223,6 +1217,9 @@ int osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
 		mcast_mgr_process_mgrp(sm, p_mgrp);
 	}
 
+	memset(sm->mlids_req, 0, sm->mlids_req_max);
+	sm->mlids_req_max = 0;
+
 	/*
 	   Walk the switches and download the tables for each.
 	 */
diff --git a/opensm/opensm/osm_sm.c b/opensm/opensm/osm_sm.c
index 50aee91..e446c9d 100644
--- a/opensm/opensm/osm_sm.c
+++ b/opensm/opensm/osm_sm.c
@@ -166,7 +166,6 @@ void osm_sm_construct(IN osm_sm_t * p_sm)
 	cl_event_construct(&p_sm->subnet_up_event);
 	cl_event_wheel_construct(&p_sm->trap_aging_tracker);
 	cl_thread_construct(&p_sm->sweeper);
-	cl_spinlock_construct(&p_sm->mgrp_lock);
 	osm_sm_mad_ctrl_construct(&p_sm->mad_ctrl);
 	osm_lid_mgr_construct(&p_sm->lid_mgr);
 	osm_ucast_mgr_construct(&p_sm->ucast_mgr);
@@ -234,8 +233,8 @@ void osm_sm_destroy(IN osm_sm_t * p_sm)
 	cl_event_destroy(&p_sm->signal_event);
 	cl_event_destroy(&p_sm->subnet_up_event);
 	cl_spinlock_destroy(&p_sm->signal_lock);
-	cl_spinlock_destroy(&p_sm->mgrp_lock);
 	cl_spinlock_destroy(&p_sm->state_lock);
+	free(p_sm->mlids_req);
 
 	osm_log(p_sm->p_log, OSM_LOG_SYS, "Exiting SM\n");	/* Format Waived */
 	OSM_LOG_EXIT(p_sm->p_log);
@@ -288,11 +287,14 @@ ib_api_status_t osm_sm_init(IN osm_sm_t * p_sm, IN osm_subn_t * p_subn,
 	if (status != CL_SUCCESS)
 		goto Exit;
 
-	cl_qlist_init(&p_sm->mgrp_list);
-
-	status = cl_spinlock_init(&p_sm->mgrp_lock);
-	if (status != CL_SUCCESS)
+	p_sm->mlids_req_max = 0;
+	p_sm->mlids_req = malloc((IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO +
+				  1) * sizeof(p_sm->mlids_req[0]));
+	if (!p_sm->mlids_req)
 		goto Exit;
+	memset(p_sm->mlids_req, 0,
+	       (IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO +
+		1) * sizeof(p_sm->mlids_req[0]));
 
 	status = osm_sm_mad_ctrl_init(&p_sm->mad_ctrl, p_sm->p_subn,
 				      p_sm->p_mad_pool, p_sm->p_vl15,
@@ -441,32 +443,15 @@ Exit:
 
 /**********************************************************************
  **********************************************************************/
-static ib_api_status_t sm_mgrp_process(IN osm_sm_t * p_sm,
-				       IN osm_mgrp_t * p_mgrp)
+static void request_mlid(osm_sm_t * sm, uint16_t mlid)
 {
-	osm_mcast_mgr_ctxt_t *ctx;
-
-	/*
-	 * 'Schedule' all the QP0 traffic for when the state manager
-	 * isn't busy trying to do something else.
-	 */
-	ctx = malloc(sizeof(*ctx));
-	if (!ctx)
-		return IB_ERROR;
-	memset(ctx, 0, sizeof(*ctx));
-	ctx->mlid = p_mgrp->mlid;
-
-	cl_spinlock_acquire(&p_sm->mgrp_lock);
-	cl_qlist_insert_tail(&p_sm->mgrp_list, &ctx->list_item);
-	cl_spinlock_release(&p_sm->mgrp_lock);
-
-	osm_sm_signal(p_sm, OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST);
-
-	return IB_SUCCESS;
+	mlid -= IB_LID_MCAST_START_HO;
+	sm->mlids_req[mlid] = 1;
+	if (sm->mlids_req_max < mlid)
+		sm->mlids_req_max = mlid;
+	osm_sm_signal(sm, OSM_SIGNAL_IDLE_TIME_PROCESS_REQUEST);
 }
 
-/**********************************************************************
- **********************************************************************/
 ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN osm_mgrp_t *mgrp,
 				  IN const ib_net64_t port_guid)
 {
@@ -519,7 +504,7 @@ ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN osm_mgrp_t *mgrp,
 		goto Exit;
 	}
 
-	status = sm_mgrp_process(p_sm, mgrp);
+	request_mlid(p_sm, cl_ntoh16(mgrp->mlid));
 Exit:
 	CL_PLOCK_RELEASE(p_sm->p_lock);
 	OSM_LOG_EXIT(p_sm->p_log);
@@ -527,8 +512,6 @@ Exit:
 	return status;
 }
 
-/**********************************************************************
- **********************************************************************/
 ib_api_status_t osm_sm_mcgrp_leave(IN osm_sm_t * p_sm, IN osm_mgrp_t *mgrp,
 				   IN const ib_net64_t port_guid)
 {
@@ -557,7 +540,7 @@ ib_api_status_t osm_sm_mcgrp_leave(IN osm_sm_t * p_sm, IN osm_mgrp_t *mgrp,
 
 	osm_port_remove_mgrp(p_port, mgrp);
 
-	status = sm_mgrp_process(p_sm, mgrp);
+	request_mlid(p_sm, cl_hton16(mgrp->mlid));
 Exit:
 	CL_PLOCK_RELEASE(p_sm->p_lock);
 	OSM_LOG_EXIT(p_sm->p_log);
-- 
1.6.4.2




More information about the general mailing list