[ofa-general] [PATCH] opensm: detect port external reset and flush cached tables

Sasha Khapyorsky sashak at voltaire.com
Tue Jul 24 14:54:41 PDT 2007


This detects port external reset by validating PortState == INIT, and
when detected flushes cached port related tables - re-reads pkey table
and drops (overwrites) SL2VL and VLArb tables.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 opensm/include/opensm/osm_port.h  |    5 +++++
 opensm/opensm/osm_port.c          |    1 +
 opensm/opensm/osm_port_info_rcv.c |    9 ++++++++-
 opensm/opensm/osm_qos.c           |    9 +++++----
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/opensm/include/opensm/osm_port.h b/opensm/include/opensm/osm_port.h
index f6c40c7..44323ab 100644
--- a/opensm/include/opensm/osm_port.h
+++ b/opensm/include/opensm/osm_port.h
@@ -118,6 +118,7 @@ typedef struct _osm_physp
 	struct _osm_physp	*p_remote_physp;
 	boolean_t		healthy;
 	uint8_t			vl_high_limit;
+	unsigned		need_update;
 	osm_dr_path_t		dr_path;
 	osm_pkey_tbl_t		pkeys;
 	ib_vl_arb_table_t	vl_arb[4];
@@ -157,6 +158,10 @@ typedef struct _osm_physp
 *		PortInfo:VLHighLimit value which installed by QoS manager
 *		and should be uploaded to port's PortInfo
 *
+*	need_update
+*		When set indicates that port was probably reset and port
+*		related tables (PKey, SL2VL, VLArb) require refreshing.
+*
 *	dr_path
 *		The directed route path to this port.
 *
diff --git a/opensm/opensm/osm_port.c b/opensm/opensm/osm_port.c
index e03e316..11cc5ca 100644
--- a/opensm/opensm/osm_port.c
+++ b/opensm/opensm/osm_port.c
@@ -118,6 +118,7 @@ osm_physp_init(
   p_physp->port_guid = port_guid;
   p_physp->port_num = port_num;
   p_physp->healthy = TRUE;
+  p_physp->need_update = 2;
   p_physp->p_node = (struct _osm_node*)p_node;
 
   osm_dr_path_init(
diff --git a/opensm/opensm/osm_port_info_rcv.c b/opensm/opensm/osm_port_info_rcv.c
index 6fe2d1d..0528e38 100644
--- a/opensm/opensm/osm_port_info_rcv.c
+++ b/opensm/opensm/osm_port_info_rcv.c
@@ -801,6 +801,12 @@ osm_pi_rcv_process(
       p_rcv->p_subn->master_sm_base_lid = p_pi->master_sm_base_lid;
     }
 
+    /* if port just inited or reached INIT state (external reset)
+       request update for port related tables */
+    p_physp->need_update =
+      (ib_port_info_get_port_state(p_pi) == IB_LINK_INIT ||
+       p_physp->need_update > 1 ) ? 1 : 0;
+
     switch( osm_node_get_type( p_node ) )
     {
     case IB_NODE_TYPE_CA:
@@ -824,7 +830,8 @@ osm_pi_rcv_process(
     /*
       Get the tables on the physp.
     */
-    __osm_pi_rcv_get_pkey_slvl_vla_tables( p_rcv, p_node, p_physp );
+    if (p_physp->need_update)
+      __osm_pi_rcv_get_pkey_slvl_vla_tables( p_rcv, p_node, p_physp );
 
   }
 
diff --git a/opensm/opensm/osm_qos.c b/opensm/opensm/osm_qos.c
index 17b7e3a..596b6d4 100644
--- a/opensm/opensm/osm_qos.c
+++ b/opensm/opensm/osm_qos.c
@@ -87,8 +87,9 @@ static ib_api_status_t vlarb_update_table_block(osm_req_t * p_req,
 	for (i = 0; i < block_length; i++)
 		block.vl_entry[i].vl &= vl_mask;
 
-	if (!memcmp(&p->vl_arb[block_num], &block,
-		     block_length * sizeof(block.vl_entry[0])))
+	if (!p->need_update &&
+	    !memcmp(&p->vl_arb[block_num], &block,
+		    block_length * sizeof(block.vl_entry[0])))
 		return IB_SUCCESS;
 
 	context.vla_context.node_guid =
@@ -170,8 +171,8 @@ static ib_api_status_t sl2vl_update_table(osm_req_t * p_req,
 		tbl.raw_vl_by_sl[i] = (vl1 << 4 ) | vl2 ;
 	}
 
-	p_tbl = osm_physp_get_slvl_tbl(p, in_port);
-	if (p_tbl && !memcmp(p_tbl, &tbl, sizeof(tbl)))
+	if (!p->need_update && (p_tbl = osm_physp_get_slvl_tbl(p, in_port)) &&
+	    !memcmp(p_tbl, &tbl, sizeof(tbl)))
 		return IB_SUCCESS;
 
 	context.slvl_context.node_guid = osm_node_get_node_guid(p_node);
-- 
1.5.3.rc2.29.gc4640f




More information about the general mailing list