Replace the unnecessarily complex switch's forwarding table implementation with a simple LFT that is implemented as plain uint8_t array.
Signed-off-by: Yevgeny Kliteynik <[EMAIL PROTECTED]> --- 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 | 54 +++++++----- opensm/opensm/osm_ucast_file.c | 2 +- opensm/opensm/osm_ucast_lash.c | 1 - opensm/opensm/osm_ucast_mgr.c | 10 ++- 11 files changed, 77 insertions(+), 143 deletions(-) diff --git a/opensm/include/opensm/osm_port_profile.h b/opensm/include/opensm/osm_port_profile.h index 9b33e3a..be1b850 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 3d9a72d..0225f9d 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 uint32_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 9be88c7..b33ac67 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; @@ -766,7 +765,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; @@ -916,7 +915,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 c0ec72d..00ab760 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 e1fe8d5..dc3187b 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 = 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 f75be65..ff3132d 100644 --- a/opensm/opensm/osm_sw_info_rcv.c +++ b/opensm/opensm/osm_sw_info_rcv.c @@ -299,8 +299,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..bdfc7d0 100644 --- a/opensm/opensm/osm_switch.c +++ b/opensm/opensm/osm_switch.c @@ -97,9 +97,26 @@ 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; + } + + /* The capacity reported by the switch includes LID 0, + so add 1 to the end of the range here for this assert. */ + CL_ASSERT(cl_ntoh16(p_si->lin_cap) <= IB_LID_UCAST_END_HO + 1); + + 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 +155,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,44 +194,36 @@ 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 uint32_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; 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); + base_lid_ho = (uint16_t) (block_id * IB_SMP_DATA_SIZE); - if (base_lid_ho <= max_lid_ho) { + if (base_lid_ho <= p_sw->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; + (uint16_t) (base_lid_ho + IB_SMP_DATA_SIZE - 1); + if (block_top_lid_ho > p_sw->max_lid_ho) + block_top_lid_ho = p_sw->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); + memcpy(p_block, &(p_sw->lft[base_lid_ho]), + block_top_lid_ho - base_lid_ho + 1); return_flag = TRUE; } @@ -359,7 +369,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 c7dbade..54a2aa3 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..cb1f5a2 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); @@ -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 _______________________________________________ general mailing list general@lists.openfabrics.org http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general