[ofa-general] [PATCH] opensm: handle port and switch tables update over handover

Sasha Khapyorsky sashak at voltaire.com
Wed Jul 25 13:37:31 PDT 2007


This cares to not use cached port and switch related tables (PKey,
SL2VL, VLArb, LFT) data after SM handover.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 opensm/include/opensm/osm_subnet.h |    5 +++++
 opensm/opensm/osm_port_info_rcv.c  |    2 +-
 opensm/opensm/osm_qos.c            |   30 +++++++++++++++++++++++-------
 opensm/opensm/osm_state_mgr.c      |    5 +++++
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/opensm/include/opensm/osm_subnet.h b/opensm/include/opensm/osm_subnet.h
index fce6b52..60dc2ff 100644
--- a/opensm/include/opensm/osm_subnet.h
+++ b/opensm/include/opensm/osm_subnet.h
@@ -579,6 +579,7 @@ typedef struct _osm_subn
   boolean_t                moved_to_master_state;
   boolean_t                first_time_master_sweep;
   boolean_t                coming_out_of_standby;
+  unsigned                 need_update;
 } osm_subn_t;
 /*
 * FIELDS
@@ -717,6 +718,10 @@ typedef struct _osm_subn
 *     The flag is set true if the SM state was standby and now changed to MASTER
 *     it is reset at the end of the sweep.
 *
+*  need_update
+*     This flag should be on during first non-master heavy (including
+*     pre-master dicovery stage)
+*
 * SEE ALSO
 *	Subnet object
 *********/
diff --git a/opensm/opensm/osm_port_info_rcv.c b/opensm/opensm/osm_port_info_rcv.c
index 0528e38..3965b88 100644
--- a/opensm/opensm/osm_port_info_rcv.c
+++ b/opensm/opensm/osm_port_info_rcv.c
@@ -830,7 +830,7 @@ osm_pi_rcv_process(
     /*
       Get the tables on the physp.
     */
-    if (p_physp->need_update)
+    if (p_physp->need_update || p_rcv->p_subn->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 596b6d4..c9ca9d8 100644
--- a/opensm/opensm/osm_qos.c
+++ b/opensm/opensm/osm_qos.c
@@ -70,6 +70,7 @@ static void qos_build_config(struct qos_config * cfg,
 static ib_api_status_t vlarb_update_table_block(osm_req_t * p_req,
 						osm_physp_t * p,
 						uint8_t port_num,
+						unsigned force_update,
 						const ib_vl_arb_table_t *table_block,
 						unsigned block_length,
 						unsigned block_num)
@@ -87,7 +88,7 @@ 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 (!p->need_update &&
+	if (!force_update &&
 	    !memcmp(&p->vl_arb[block_num], &block,
 		    block_length * sizeof(block.vl_entry[0])))
 		return IB_SUCCESS;
@@ -106,6 +107,7 @@ static ib_api_status_t vlarb_update_table_block(osm_req_t * p_req,
 
 static ib_api_status_t vlarb_update(osm_req_t * p_req,
 				    osm_physp_t * p, uint8_t port_num,
+				    unsigned force_update,
 				    const struct qos_config *qcfg)
 {
 	ib_api_status_t status = IB_SUCCESS;
@@ -116,6 +118,7 @@ static ib_api_status_t vlarb_update(osm_req_t * p_req,
 		len = p_pi->vl_arb_low_cap < IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK ?
 		    p_pi->vl_arb_low_cap : IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK;
 		if ((status = vlarb_update_table_block(p_req, p, port_num,
+						       force_update,
 						       &qcfg->vlarb_low[0],
 						       len, 0)) != IB_SUCCESS)
 			return status;
@@ -123,6 +126,7 @@ static ib_api_status_t vlarb_update(osm_req_t * p_req,
 	if (p_pi->vl_arb_low_cap > IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK) {
 		len = p_pi->vl_arb_low_cap % IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK;
 		if ((status = vlarb_update_table_block(p_req, p, port_num,
+						       force_update,
 						       &qcfg->vlarb_low[1],
 						       len, 1)) != IB_SUCCESS)
 			return status;
@@ -131,6 +135,7 @@ static ib_api_status_t vlarb_update(osm_req_t * p_req,
 		len = p_pi->vl_arb_high_cap < IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK ?
 		    p_pi->vl_arb_high_cap : IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK;
 		if ((status = vlarb_update_table_block(p_req, p, port_num,
+						       force_update,
 						       &qcfg->vlarb_high[0],
 						       len, 2)) != IB_SUCCESS)
 			return status;
@@ -138,6 +143,7 @@ static ib_api_status_t vlarb_update(osm_req_t * p_req,
 	if (p_pi->vl_arb_high_cap > IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK) {
 		len = p_pi->vl_arb_high_cap % IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK;
 		if ((status = vlarb_update_table_block(p_req, p, port_num,
+						       force_update,
 						       &qcfg->vlarb_high[1],
 						       len, 3)) != IB_SUCCESS)
 			return status;
@@ -149,6 +155,7 @@ static ib_api_status_t vlarb_update(osm_req_t * p_req,
 static ib_api_status_t sl2vl_update_table(osm_req_t * p_req,
 					  osm_physp_t * p, uint8_t in_port,
 					  uint8_t out_port,
+					  unsigned force_update,
 					  const ib_slvl_table_t * sl2vl_table)
 {
 	osm_madw_context_t context;
@@ -171,7 +178,7 @@ static ib_api_status_t sl2vl_update_table(osm_req_t * p_req,
 		tbl.raw_vl_by_sl[i] = (vl1 << 4 ) | vl2 ;
 	}
 
-	if (!p->need_update && (p_tbl = osm_physp_get_slvl_tbl(p, in_port)) &&
+	if (!force_update && (p_tbl = osm_physp_get_slvl_tbl(p, in_port)) &&
 	    !memcmp(p_tbl, &tbl, sizeof(tbl)))
 		return IB_SUCCESS;
 
@@ -187,6 +194,7 @@ static ib_api_status_t sl2vl_update_table(osm_req_t * p_req,
 
 static ib_api_status_t sl2vl_update(osm_req_t * p_req, osm_port_t * p_port,
 				    osm_physp_t * p, uint8_t port_num,
+				    unsigned force_update,
 				    const struct qos_config *qcfg)
 {
 	ib_api_status_t status;
@@ -209,7 +217,8 @@ static ib_api_status_t sl2vl_update(osm_req_t * p_req, osm_port_t * p_port,
 
 	for (i = 0; i < num_ports; i++) {
 		status =
-		    sl2vl_update_table(p_req, p, i, port_num, &qcfg->sl2vl);
+		    sl2vl_update_table(p_req, p, i, port_num,
+				       force_update, &qcfg->sl2vl);
 		if (status != IB_SUCCESS)
 			return status;
 	}
@@ -220,6 +229,7 @@ static ib_api_status_t sl2vl_update(osm_req_t * p_req, osm_port_t * p_port,
 static ib_api_status_t qos_physp_setup(osm_log_t * p_log, osm_req_t * p_req,
 				       osm_port_t * p_port, osm_physp_t * p,
 				       uint8_t port_num,
+				       unsigned force_update,
 				       const struct qos_config *qcfg)
 {
 	ib_api_status_t status;
@@ -230,7 +240,7 @@ static ib_api_status_t qos_physp_setup(osm_log_t * p_log, osm_req_t * p_req,
 	p->vl_high_limit = qcfg->vl_high_limit;
 
 	/* setup VLArbitration */
-	status = vlarb_update(p_req, p, port_num, qcfg);
+	status = vlarb_update(p_req, p, port_num, force_update, qcfg);
 	if (status != IB_SUCCESS) {
 		osm_log(p_log, OSM_LOG_ERROR,
 			"qos_physp_setup: ERR 6202 : "
@@ -241,7 +251,7 @@ static ib_api_status_t qos_physp_setup(osm_log_t * p_log, osm_req_t * p_req,
 	}
 
 	/* setup SL2VL tables */
-	status = sl2vl_update(p_req, p_port, p, port_num, qcfg);
+	status = sl2vl_update(p_req, p_port, p, port_num, force_update, qcfg);
 	if (status != IB_SUCCESS) {
 		osm_log(p_log, OSM_LOG_ERROR,
 			"qos_physp_setup: ERR 6203 : "
@@ -265,6 +275,7 @@ osm_signal_t osm_qos_setup(osm_opensm_t * p_osm)
 	osm_physp_t *p_physp;
 	osm_node_t *p_node;
 	ib_api_status_t status;
+	unsigned force_update;
 	uint8_t i;
 
 	if (p_osm->subn.opt.no_qos)
@@ -296,9 +307,12 @@ osm_signal_t osm_qos_setup(osm_opensm_t * p_osm)
 				p_physp = osm_node_get_physp_ptr(p_node, i);
 				if (!osm_physp_is_valid(p_physp))
 					continue;
+				force_update = p_physp->need_update ||
+					p_osm->subn.need_update;
 				status =
 				    qos_physp_setup(&p_osm->log, &p_osm->sm.req,
-						    p_port, p_physp, i, &swe_config);
+						    p_port, p_physp, i,
+						    force_update, &swe_config);
 			}
 			/* skip base port 0 */
 			if (!ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
@@ -314,8 +328,10 @@ osm_signal_t osm_qos_setup(osm_opensm_t * p_osm)
 		if (!osm_physp_is_valid(p_physp))
 			continue;
 
+		force_update = p_physp->need_update || p_osm->subn.need_update;
 		status = qos_physp_setup(&p_osm->log, &p_osm->sm.req,
-					 p_port, p_physp, 0, cfg);
+					 p_port, p_physp, 0,
+					 force_update, cfg);
 	}
 
 	cl_plock_release(&p_osm->lock);
diff --git a/opensm/opensm/osm_state_mgr.c b/opensm/opensm/osm_state_mgr.c
index 7efbe2a..a15f3b4 100644
--- a/opensm/opensm/osm_state_mgr.c
+++ b/opensm/opensm/osm_state_mgr.c
@@ -1938,6 +1938,10 @@ osm_state_mgr_process(
                          "osm_state_mgr_process: ERR 331A: "
                          "osm_subn_rescan_conf_file failed\n" );
                }
+
+	       if (p_mgr->p_subn->sm_state != IB_SMINFO_STATE_MASTER)
+	          p_mgr->p_subn->need_update = 1;
+
                status = __osm_state_mgr_sweep_hop_0( p_mgr );
                if( status == IB_SUCCESS )
                {
@@ -2742,6 +2746,7 @@ Idle:
                {
                   p_mgr->p_subn->first_time_master_sweep = FALSE;
                }
+               p_mgr->p_subn->need_update = 0;
 
                __osm_topology_file_create( p_mgr );
                __osm_state_mgr_report( p_mgr );
-- 
1.5.3.rc2.29.gc4640f




More information about the general mailing list