@@ -126,6 +126,9 @@ struct osm_routing_engine {
int (*build_lid_matrices) (void *context);
int (*ucast_build_fwd_tables) (void *context);
void (*ucast_dump_tables) (void *context);
+ void (*update_sl2vl)(void *context, IN osm_physp_t *port,
+ IN uint8_t in_port_num, IN uint8_t out_port_num,
+ IN OUT ib_slvl_table_t *t);
void (*delete) (void *context);
struct osm_routing_engine *next;
};
@@ -147,6 +150,15 @@ struct osm_routing_engine {
* ucast_dump_tables
* The callback for dumping unicast routing tables.
*
+* update_sl2vl(void *context, IN osm_physp_t *port,
+* IN uint8_t in_port_num, IN uint8_t out_port_num,
+* OUT ib_slvl_table_t *t)
+* The callback to allow routing engine input for SL2VL maps.
+* *port is the phyical port for which the SL2VL map is to be
+* updated. For switches, in_port_num/out_port_num identify
+* which part of the SL2VL map to update. For router/HCA ports,
+* in_port_num/out_port_num should be ignored.
+*
* delete
* The delete method, may be used for routing engine
* internals cleanup.
@@ -207,6 +207,7 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
osm_physp_t *p0, *p;
unsigned force_update;
unsigned num_ports = osm_node_get_num_physp(node);
+ struct osm_routing_engine *re = sm->p_subn->p_osm->routing_engine_used;
int ret = 0;
unsigned i, j;
@@ -223,7 +224,7 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
return ret;
if (ib_switch_info_get_opt_sl2vlmapping(&node->sw->switch_info) &&
- sm->p_subn->opt.use_optimized_slvl) {
+ sm->p_subn->opt.use_optimized_slvl && !re->update_sl2vl) {
p = osm_node_get_physp_ptr(node, 1);
force_update = p->need_update || sm->p_subn->need_update;
return sl2vl_update_table(sm, p, 1, 0x30000, force_update,
@@ -233,10 +234,20 @@ static int qos_extports_setup(osm_sm_t * sm, osm_node_t *node,
for (i = 1; i < num_ports; i++) {
p = osm_node_get_physp_ptr(node, i);
force_update = p->need_update || sm->p_subn->need_update;
- for (j = 0; j < num_ports; j++)
+ for (j = 0; j < num_ports; j++) {
+ const ib_slvl_table_t *port_sl2vl = &qcfg->sl2vl;
+ ib_slvl_table_t routing_sl2vl;
+
+ if (re->update_sl2vl) {
+ routing_sl2vl = *port_sl2vl;
+ re->update_sl2vl(re->context,
+ p, i, j, &routing_sl2vl);
+ port_sl2vl = &routing_sl2vl;
+ }
if (sl2vl_update_table(sm, p, i, i << 8 | j,
- force_update, &qcfg->sl2vl))
+ force_update, port_sl2vl))
ret = -1;
+ }
}
return ret;
@@ -246,6 +257,9 @@ static int qos_endport_setup(osm_sm_t * sm, osm_physp_t * p,
const struct qos_config *qcfg)
{
unsigned force_update = p->need_update || sm->p_subn->need_update;
+ struct osm_routing_engine *re = sm->p_subn->p_osm->routing_engine_used;
+ const ib_slvl_table_t *port_sl2vl = &qcfg->sl2vl;
+ ib_slvl_table_t routing_sl2vl;
p->vl_high_limit = qcfg->vl_high_limit;
if (vlarb_update(sm, p, 0, force_update, qcfg))
@@ -254,7 +268,12 @@ static int qos_endport_setup(osm_sm_t * sm, osm_physp_t * p,
if (!(p->port_info.capability_mask & IB_PORT_CAP_HAS_SL_MAP))
return 0;
- if (sl2vl_update_table(sm, p, 0, 0, force_update, &qcfg->sl2vl))
+ if (re->update_sl2vl) {
+ routing_sl2vl = *port_sl2vl;
+ re->update_sl2vl(re->context, p, 0, 0, &routing_sl2vl);
+ port_sl2vl = &routing_sl2vl;
+ }
+ if (sl2vl_update_table(sm, p, 0, 0, force_update, port_sl2vl))
return -1;
return 0;
@@ -1141,6 +1141,7 @@ static void do_sweep(osm_sm_t * sm)
sm->p_subn->ignore_existing_lfts = TRUE;
osm_ucast_mgr_process(&sm->ucast_mgr);
+ osm_qos_setup(sm->p_subn->p_osm);
/* Reset flag */
sm->p_subn->ignore_existing_lfts = FALSE;
@@ -1259,8 +1260,6 @@ repeat_discovery:
osm_pkey_mgr_process(sm->p_subn->p_osm);
- osm_qos_setup(sm->p_subn->p_osm);
-
/* try to restore SA DB (this should be before lid_mgr
because we may want to disable clients reregistration
when SA DB is restored) */
@@ -1301,6 +1300,8 @@ repeat_discovery:
osm_ucast_cache_process(&sm->ucast_mgr))
osm_ucast_mgr_process(&sm->ucast_mgr);
+ osm_qos_setup(sm->p_subn->p_osm);
+
if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
return;