[ofa-general] [PATCH 1/2 v2] opensm: replace switch's fwd_tbl with simple LFT

Yevgeny Kliteynik kliteyn at dev.mellanox.co.il
Wed Oct 29 06:01:48 PDT 2008


Replace the unnecessarily complex switch's forwarding table
implementation with a simple LFT that is implemented as plain
uint8_t array.

[v2- fixed two remarks that I got with the previous version]

Signed-off-by: Yevgeny Kliteynik <kliteyn at dev.mellanox.co.il>
---
 opensm/include/opensm/osm_port_profile.h |    1 -
 opensm/include/opensm/osm_router.h       |    1 -
 opensm/include/opensm/osm_switch.h       |  138 +++++++-----------------------
 opensm/opensm/osm_console.c              |    5 +-
 opensm/opensm/osm_lin_fwd_rcv.c          |    2 +-
 opensm/opensm/osm_sa_lft_record.c        |    2 +-
 opensm/opensm/osm_sw_info_rcv.c          |    4 +-
 opensm/opensm/osm_switch.c               |   68 ++++++---------
 opensm/opensm/osm_ucast_file.c           |    2 +-
 opensm/opensm/osm_ucast_lash.c           |    1 -
 opensm/opensm/osm_ucast_mgr.c            |   12 ++-
 11 files changed, 73 insertions(+), 163 deletions(-)

diff --git a/opensm/include/opensm/osm_port_profile.h b/opensm/include/opensm/osm_port_profile.h
index 00d83e4..fd22719 100644
--- a/opensm/include/opensm/osm_port_profile.h
+++ b/opensm/include/opensm/osm_port_profile.h
@@ -51,7 +51,6 @@
 #include <opensm/osm_subnet.h>
 #include <opensm/osm_node.h>
 #include <opensm/osm_port.h>
-#include <opensm/osm_fwd_tbl.h>
 #include <opensm/osm_mcast_tbl.h>

 #ifdef __cplusplus
diff --git a/opensm/include/opensm/osm_router.h b/opensm/include/opensm/osm_router.h
index 8cabdf8..4901aca 100644
--- a/opensm/include/opensm/osm_router.h
+++ b/opensm/include/opensm/osm_router.h
@@ -48,7 +48,6 @@
 #include <opensm/osm_madw.h>
 #include <opensm/osm_node.h>
 #include <opensm/osm_port.h>
-#include <opensm/osm_fwd_tbl.h>
 #include <opensm/osm_mcast_tbl.h>
 #include <opensm/osm_port_profile.h>

diff --git a/opensm/include/opensm/osm_switch.h b/opensm/include/opensm/osm_switch.h
index 98eb64d..a27af20 100644
--- a/opensm/include/opensm/osm_switch.h
+++ b/opensm/include/opensm/osm_switch.h
@@ -48,7 +48,6 @@
 #include <opensm/osm_madw.h>
 #include <opensm/osm_node.h>
 #include <opensm/osm_port.h>
-#include <opensm/osm_fwd_tbl.h>
 #include <opensm/osm_mcast_tbl.h>
 #include <opensm/osm_port_profile.h>

@@ -101,7 +100,7 @@ typedef struct osm_switch {
 	uint16_t num_hops;
 	uint8_t **hops;
 	osm_port_profile_t *p_prof;
-	osm_fwd_tbl_t fwd_tbl;
+	uint8_t *lft;
 	uint8_t *lft_buf;
 	osm_mcast_tbl_t mcast_tbl;
 	uint32_t discovery_count;
@@ -135,8 +134,8 @@ typedef struct osm_switch {
 *	p_prof
 *		Pointer to array of Port Profile objects for this switch.
 *
-*	fwd_tbl
-*		This switch's forwarding table.
+*	lft
+*		This switch's linear forwarding table.
 *
 *	lft_buf
 *		This switch's linear forwarding table, as was
@@ -275,33 +274,6 @@ osm_switch_get_hop_count(IN const osm_switch_t * const p_sw,
 * SEE ALSO
 *********/

-/****f* OpenSM: Switch/osm_switch_get_fwd_tbl_ptr
-* NAME
-*	osm_switch_get_fwd_tbl_ptr
-*
-* DESCRIPTION
-*	Returns a pointer to the switch's forwarding table.
-*
-* SYNOPSIS
-*/
-static inline osm_fwd_tbl_t *osm_switch_get_fwd_tbl_ptr(IN const osm_switch_t *
-							const p_sw)
-{
-	return ((osm_fwd_tbl_t *) & p_sw->fwd_tbl);
-}
-/*
-* PARAMETERS
-*	p_sw
-*		[in] Pointer to a Switch object.
-*
-* RETURN VALUES
-*	Returns a pointer to the switch's forwarding table.
-*
-* NOTES
-*
-* SEE ALSO
-*********/
-
 /****f* OpenSM: Switch/osm_switch_set_hops
 * NAME
 *	osm_switch_set_hops
@@ -437,7 +409,9 @@ static inline uint8_t
 osm_switch_get_port_by_lid(IN const osm_switch_t * const p_sw,
 			   IN const uint16_t lid_ho)
 {
-	return (osm_fwd_tbl_get(&p_sw->fwd_tbl, lid_ho));
+	if (lid_ho == 0 || lid_ho > IB_LID_UCAST_END_HO)
+		return OSM_NO_PATH;
+	return p_sw->lft[lid_ho];
 }
 /*
 * PARAMETERS
@@ -500,12 +474,13 @@ static inline osm_physp_t *osm_switch_get_route_by_lid(IN const osm_switch_t *
 						       const p_sw,
 						       IN const ib_net16_t lid)
 {
-	uint8_t port_num;
+	uint8_t port_num = OSM_NO_PATH;

 	CL_ASSERT(p_sw);
 	CL_ASSERT(lid);

-	port_num = osm_fwd_tbl_get(&p_sw->fwd_tbl, cl_ntoh16(lid));
+	port_num = osm_switch_get_port_by_lid(p_sw, cl_ntoh16(lid));
+
 	/*
 	   In order to avoid holes in the subnet (usually happens when
 	   running UPDN algorithm), i.e. cases where port is
@@ -572,35 +547,6 @@ osm_switch_sp0_is_lmc_capable(IN const osm_switch_t * const p_sw,
 * SEE ALSO
 *********/

-/****f* OpenSM: Switch/osm_switch_get_max_block_id
-* NAME
-*	osm_switch_get_max_block_id
-*
-* DESCRIPTION
-*	Returns the maximum block ID (host order) of this switch.
-*
-* SYNOPSIS
-*/
-static inline uint32_t
-osm_switch_get_max_block_id(IN const osm_switch_t * const p_sw)
-{
-	return ((uint32_t) (osm_fwd_tbl_get_size(&p_sw->fwd_tbl) /
-			    osm_fwd_tbl_get_lids_per_block(&p_sw->fwd_tbl)));
-}
-/*
-* PARAMETERS
-*	p_sw
-*		[in] Pointer to an osm_switch_t object.
-*
-* RETURN VALUES
-*	Returns the maximum block ID (host order) of this switch.
-*
-* NOTES
-*
-* SEE ALSO
-*	Switch object
-*********/
-
 /****f* OpenSM: Switch/osm_switch_get_max_block_id_in_use
 * NAME
 *	osm_switch_get_max_block_id_in_use
@@ -614,9 +560,8 @@ osm_switch_get_max_block_id(IN const osm_switch_t * const p_sw)
 static inline uint16_t
 osm_switch_get_max_block_id_in_use(IN const osm_switch_t * const p_sw)
 {
-	return (osm_fwd_tbl_get_max_block_id_in_use(&p_sw->fwd_tbl,
-						    cl_ntoh16(p_sw->switch_info.
-							      lin_top)));
+	return (uint16_t)(cl_ntoh16(p_sw->switch_info.lin_top) /
+			  IB_SMP_DATA_SIZE);
 }
 /*
 * PARAMETERS
@@ -632,19 +577,19 @@ osm_switch_get_max_block_id_in_use(IN const osm_switch_t * const p_sw)
 *	Switch object
 *********/

-/****f* OpenSM: Switch/osm_switch_get_fwd_tbl_block
+/****f* OpenSM: Switch/osm_switch_get_lft_block
 * NAME
-*	osm_switch_get_fwd_tbl_block
+*	osm_switch_get_lft_block
 *
 * DESCRIPTION
-*	Retrieve a forwarding table block.
+*	Retrieve a linear forwarding table block.
 *
 * SYNOPSIS
 */
 boolean_t
-osm_switch_get_fwd_tbl_block(IN const osm_switch_t * const p_sw,
-			     IN const uint32_t block_id,
-			     OUT uint8_t * const p_block);
+osm_switch_get_lft_block(IN const osm_switch_t * const p_sw,
+			 IN const uint16_t block_id,
+			 OUT uint8_t * const p_block);
 /*
 * PARAMETERS
 *	p_sw
@@ -758,22 +703,30 @@ osm_switch_count_path(IN osm_switch_t * const p_sw, IN const uint8_t port)
 * SEE ALSO
 *********/

-/****f* OpenSM: Switch/osm_switch_set_ft_block
+/****f* OpenSM: Switch/osm_switch_set_lft_block
 * NAME
-*	osm_switch_set_ft_block
+*	osm_switch_set_lft_block
 *
 * DESCRIPTION
-*	Copies in the specified block into the switch's Forwarding Table object.
+*	Copies in the specified block into
+*	the switch's Linear Forwarding Table.
 *
 * SYNOPSIS
 */
 static inline ib_api_status_t
-osm_switch_set_ft_block(IN osm_switch_t * const p_sw,
-			IN const uint8_t * const p_block,
-			IN const uint32_t block_num)
+osm_switch_set_lft_block(IN osm_switch_t * const p_sw,
+			 IN const uint8_t * const p_block,
+			 IN const uint32_t block_num)
 {
+	uint16_t lid_start =
+		(uint16_t) (block_num * IB_SMP_DATA_SIZE);
 	CL_ASSERT(p_sw);
-	return (osm_fwd_tbl_set_block(&p_sw->fwd_tbl, p_block, block_num));
+
+	if (lid_start + IB_SMP_DATA_SIZE > IB_LID_UCAST_END_HO)
+		return IB_INVALID_PARAMETER;
+
+	memcpy(&p_sw->lft[lid_start], p_block, IB_SMP_DATA_SIZE);
+	return IB_SUCCESS;
 }
 /*
 * PARAMETERS
@@ -1044,33 +997,6 @@ osm_switch_recommend_mcast_path(IN osm_switch_t * const p_sw,
 * SEE ALSO
 *********/

-/****f* OpenSM: Switch/osm_switch_get_fwd_tbl_size
-* NAME
-*	osm_switch_get_fwd_tbl_size
-*
-* DESCRIPTION
-*	Returns the number of entries available in the forwarding table.
-*
-* SYNOPSIS
-*/
-static inline uint16_t
-osm_switch_get_fwd_tbl_size(IN const osm_switch_t * const p_sw)
-{
-	return (osm_fwd_tbl_get_size(&p_sw->fwd_tbl));
-}
-/*
-* PARAMETERS
-*	p_sw
-*		[in] Pointer to the switch.
-*
-* RETURN VALUE
-*	Returns the number of entries available in the forwarding table.
-*
-* NOTES
-*
-* SEE ALSO
-*********/
-
 /****f* OpenSM: Switch/osm_switch_get_mcast_fwd_tbl_size
 * NAME
 *	osm_switch_get_mcast_fwd_tbl_size
diff --git a/opensm/opensm/osm_console.c b/opensm/opensm/osm_console.c
index 18168ff..d9bbbc2 100644
--- a/opensm/opensm/osm_console.c
+++ b/opensm/opensm/osm_console.c
@@ -52,7 +52,6 @@
 #include <opensm/osm_console.h>
 #include <complib/cl_passivelock.h>
 #include <opensm/osm_perfmgr.h>
-#include <opensm/osm_fwd_tbl.h>

 struct command {
 	char *name;
@@ -765,7 +764,7 @@ static void switchbalance_check(osm_opensm_t * p_osm,
 			continue;

 		for (lid_ho = min_lid_ho; lid_ho <= max_lid_ho; lid_ho++) {
-			port_num = osm_fwd_tbl_get(&(p_sw->fwd_tbl), lid_ho);
+			port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);
 			if (port_num == OSM_NO_PATH)
 				continue;

@@ -915,7 +914,7 @@ static void lidbalance_check(osm_opensm_t * p_osm,
 			boolean_t rem_node_found = FALSE;
 			unsigned int indx = 0;

-			port_num = osm_fwd_tbl_get(&(p_sw->fwd_tbl), lid_ho);
+			port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);
 			if (port_num == OSM_NO_PATH)
 				continue;

diff --git a/opensm/opensm/osm_lin_fwd_rcv.c b/opensm/opensm/osm_lin_fwd_rcv.c
index c5cbfb5..c3d8633 100644
--- a/opensm/opensm/osm_lin_fwd_rcv.c
+++ b/opensm/opensm/osm_lin_fwd_rcv.c
@@ -87,7 +87,7 @@ void osm_lft_rcv_process(IN void *context, IN void *data)
 			"LFT received for nonexistent node "
 			"0x%" PRIx64 "\n", cl_ntoh64(node_guid));
 	} else {
-		status = osm_switch_set_ft_block(p_sw, p_block, block_num);
+		status = osm_switch_set_lft_block(p_sw, p_block, block_num);
 		if (status != IB_SUCCESS) {
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0402: "
 				"Setting forwarding table block failed (%s)"
diff --git a/opensm/opensm/osm_sa_lft_record.c b/opensm/opensm/osm_sa_lft_record.c
index cdca430..d84a6a5 100644
--- a/opensm/opensm/osm_sa_lft_record.c
+++ b/opensm/opensm/osm_sa_lft_record.c
@@ -100,7 +100,7 @@ __osm_lftr_rcv_new_lftr(IN osm_sa_t * sa,
 	p_rec_item->rec.block_num = cl_hton16(block);

 	/* copy the lft block */
-	osm_switch_get_fwd_tbl_block(p_sw, block, p_rec_item->rec.lft);
+	osm_switch_get_lft_block(p_sw, block, p_rec_item->rec.lft);

 	cl_qlist_insert_tail(p_list, &p_rec_item->list_item);

diff --git a/opensm/opensm/osm_sw_info_rcv.c b/opensm/opensm/osm_sw_info_rcv.c
index 6ee1538..e9973e3 100644
--- a/opensm/opensm/osm_sw_info_rcv.c
+++ b/opensm/opensm/osm_sw_info_rcv.c
@@ -298,8 +298,8 @@ __osm_si_rcv_process_new(IN osm_sm_t * sm,
 	}

 	/* set subnet max unicast lid to the minimum LinearFDBCap of all switches */
-	if (p_sw->fwd_tbl.p_lin_tbl->size < sm->p_subn->max_ucast_lid_ho) {
-		sm->p_subn->max_ucast_lid_ho = p_sw->fwd_tbl.p_lin_tbl->size;
+	if (cl_ntoh16(p_si->lin_cap) < sm->p_subn->max_ucast_lid_ho) {
+		sm->p_subn->max_ucast_lid_ho = cl_ntoh16(p_si->lin_cap);
 		OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 			"Subnet max unicast lid is 0x%X\n",
 			sm->p_subn->max_ucast_lid_ho);
diff --git a/opensm/opensm/osm_switch.c b/opensm/opensm/osm_switch.c
index 9bf76e0..4b07dbc 100644
--- a/opensm/opensm/osm_switch.c
+++ b/opensm/opensm/osm_switch.c
@@ -97,9 +97,22 @@ osm_switch_init(IN osm_switch_t * const p_sw,
 	p_sw->num_ports = num_ports;
 	p_sw->need_update = 2;

-	status = osm_fwd_tbl_init(&p_sw->fwd_tbl, p_si);
-	if (status != IB_SUCCESS)
+	/* Initiate the linear forwarding table */
+
+	if (!p_si->lin_cap) {
+		/* This switch does not support linear forwarding tables */
+		status = IB_UNSUPPORTED;
+		goto Exit;
+	}
+
+	p_sw->lft = malloc(IB_LID_UCAST_END_HO + 1);
+	if (!p_sw->lft) {
+		status = IB_INSUFFICIENT_MEMORY;
 		goto Exit;
+	}
+
+	/* Initialize the table to OSM_NO_PATH, which is "invalid port" */
+	memset(p_sw->lft, OSM_NO_PATH, IB_LID_UCAST_END_HO + 1);

 	p_sw->lft_buf = malloc(IB_LID_UCAST_END_HO + 1);
 	if (!p_sw->lft_buf) {
@@ -138,7 +151,8 @@ void osm_switch_delete(IN OUT osm_switch_t ** const pp_sw)

 	osm_mcast_tbl_destroy(&p_sw->mcast_tbl);
 	free(p_sw->p_prof);
-	osm_fwd_tbl_destroy(&p_sw->fwd_tbl);
+	if (p_sw->lft)
+		free(p_sw->lft);
 	if (p_sw->lft_buf)
 		free(p_sw->lft_buf);
 	if (p_sw->hops) {
@@ -176,49 +190,21 @@ osm_switch_t *osm_switch_new(IN osm_node_t * const p_node,
 /**********************************************************************
  **********************************************************************/
 boolean_t
-osm_switch_get_fwd_tbl_block(IN const osm_switch_t * const p_sw,
-			     IN const uint32_t block_id,
-			     OUT uint8_t * const p_block)
+osm_switch_get_lft_block(IN const osm_switch_t * const p_sw,
+			 IN const uint16_t block_id,
+			 OUT uint8_t * const p_block)
 {
-	uint16_t base_lid_ho;
-	uint16_t max_lid_ho;
-	uint16_t lid_ho;
-	uint16_t block_top_lid_ho;
-	uint32_t lids_per_block;
-	osm_fwd_tbl_t *p_tbl;
-	boolean_t return_flag = FALSE;
+	uint16_t base_lid_ho = block_id * IB_SMP_DATA_SIZE;

 	CL_ASSERT(p_sw);
 	CL_ASSERT(p_block);

-	p_tbl = osm_switch_get_fwd_tbl_ptr(p_sw);
-	max_lid_ho = p_sw->max_lid_ho;
-	lids_per_block = osm_fwd_tbl_get_lids_per_block(&p_sw->fwd_tbl);
-	base_lid_ho = (uint16_t) (block_id * lids_per_block);
-
-	if (base_lid_ho <= max_lid_ho) {
-		/* Initialize LIDs in block to invalid port number. */
-		memset(p_block, OSM_NO_PATH, IB_SMP_DATA_SIZE);
-		/*
-		   Determine the range of LIDs we can return with this block.
-		 */
-		block_top_lid_ho =
-		    (uint16_t) (base_lid_ho + lids_per_block - 1);
-		if (block_top_lid_ho > max_lid_ho)
-			block_top_lid_ho = max_lid_ho;
-
-		/*
-		   Configure the forwarding table with the routing
-		   information for the specified block of LIDs.
-		 */
-		for (lid_ho = base_lid_ho; lid_ho <= block_top_lid_ho; lid_ho++)
-			p_block[lid_ho - base_lid_ho] =
-			    osm_fwd_tbl_get(p_tbl, lid_ho);
-
-		return_flag = TRUE;
-	}
+	if (base_lid_ho > p_sw->max_lid_ho)
+		return FALSE;

-	return (return_flag);
+	CL_ASSERT(base_lid_ho + IB_SMP_DATA_SIZE <= IB_LID_UCAST_END_HO);
+	memcpy(p_block, &(p_sw->lft[base_lid_ho]), IB_SMP_DATA_SIZE);
+	return TRUE;
 }

 /**********************************************************************
@@ -359,7 +345,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 	   4. the port has min-hops to the target (avoid loops)
 	 */
 	if (!ignore_existing) {
-		port_num = osm_fwd_tbl_get(&p_sw->fwd_tbl, lid_ho);
+		port_num = osm_switch_get_port_by_lid(p_sw, lid_ho);

 		if (port_num != OSM_NO_PATH) {
 			CL_ASSERT(port_num < num_ports);
diff --git a/opensm/opensm/osm_ucast_file.c b/opensm/opensm/osm_ucast_file.c
index a6edf5d..865ad82 100644
--- a/opensm/opensm/osm_ucast_file.c
+++ b/opensm/opensm/osm_ucast_file.c
@@ -83,7 +83,7 @@ static void add_path(osm_opensm_t * p_osm,
 	uint8_t old_port;

 	new_lid = port_guid ? remap_lid(p_osm, lid, port_guid) : lid;
-	old_port = osm_fwd_tbl_get(osm_switch_get_fwd_tbl_ptr(p_sw), new_lid);
+	old_port = osm_switch_get_port_by_lid(p_sw, new_lid);
 	if (old_port != OSM_NO_PATH && old_port != port_num) {
 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
 			"LID collision is detected on switch "
diff --git a/opensm/opensm/osm_ucast_lash.c b/opensm/opensm/osm_ucast_lash.c
index 1036c9f..c082798 100644
--- a/opensm/opensm/osm_ucast_lash.c
+++ b/opensm/opensm/osm_ucast_lash.c
@@ -52,7 +52,6 @@
 #include <opensm/osm_switch.h>
 #include <opensm/osm_opensm.h>
 #include <opensm/osm_log.h>
-#include <opensm/osm_fwd_tbl.h>

 /* //////////////////////////// */
 /*  Local types                 */
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index 3bc3912..adb6688 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -247,7 +247,7 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 		lid_ho, min_lid_ho, max_lid_ho);

 	/* TODO - This should be runtime error, not a CL_ASSERT() */
-	CL_ASSERT(max_lid_ho < osm_switch_get_fwd_tbl_size(p_sw));
+	CL_ASSERT(max_lid_ho <= IB_LID_UCAST_END_HO);

 	node_guid = osm_node_get_node_guid(p_sw->p_node);

@@ -320,7 +320,7 @@ int osm_ucast_mgr_set_fwd_table(IN osm_ucast_mgr_t * const p_mgr,
 	osm_madw_context_t context;
 	ib_api_status_t status;
 	ib_switch_info_t si;
-	uint32_t block_id_ho = 0;
+	uint16_t block_id_ho = 0;
 	uint8_t block[IB_SMP_DATA_SIZE];
 	boolean_t set_swinfo_require = FALSE;
 	uint16_t lin_top;
@@ -393,17 +393,19 @@ int osm_ucast_mgr_set_fwd_table(IN osm_ucast_mgr_t * const p_mgr,
 	context.lft_context.set_method = TRUE;

 	for (block_id_ho = 0;
-	     osm_switch_get_fwd_tbl_block(p_sw, block_id_ho, block);
+	     osm_switch_get_lft_block(p_sw, block_id_ho, block);
 	     block_id_ho++) {
 		if (!p_sw->need_update &&
-		    !memcmp(block, p_sw->lft_buf + block_id_ho * 64, 64))
+		    !memcmp(block,
+			    p_sw->lft_buf + block_id_ho * IB_SMP_DATA_SIZE,
+			    IB_SMP_DATA_SIZE))
 			continue;

 		OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
 			"Writing FT block %u\n", block_id_ho);

 		status = osm_req_set(p_mgr->sm, p_path,
-				     p_sw->lft_buf + block_id_ho * 64,
+				     p_sw->lft_buf + block_id_ho * IB_SMP_DATA_SIZE,
 				     sizeof(block),
 				     IB_MAD_ATTR_LIN_FWD_TBL,
 				     cl_hton32(block_id_ho),
-- 
1.5.1.4





More information about the general mailing list