[ofa-general] [PATCH 1/2] opensm: replace switch's fwd_tbl with simple LFT
Yevgeny Kliteynik
kliteyn at dev.mellanox.co.il
Thu Oct 16 14:36:23 PDT 2008
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 <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 | 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
More information about the general
mailing list