@@ -288,7 +288,9 @@ int osm_qos_setup(osm_opensm_t * p_osm)
int ret = 0;
uint8_t i;
- if (!p_osm->subn.opt.qos)
+ if (!(p_osm->subn.opt.qos ||
+ (p_osm->routing_engine_used &&
+ p_osm->routing_engine_used->update_sl2vl)))
return 0;
OSM_LOG_ENTER(&p_osm->log);
@@ -305,7 +307,8 @@ int osm_qos_setup(osm_opensm_t * p_osm)
cl_plock_excl_acquire(&p_osm->lock);
/* read QoS policy config file */
- osm_qos_parse_policy_file(&p_osm->subn);
+ if (p_osm->subn.opt.qos)
+ osm_qos_parse_policy_file(&p_osm->subn);
p_tbl = &p_osm->subn.port_guid_tbl;
p_next = cl_qmap_head(p_tbl);
@@ -1044,6 +1044,8 @@ static void subn_verify_qos_set(osm_qos_options_t *set, const char *prefix,
int osm_subn_verify_config(IN osm_subn_opt_t * p_opts)
{
+ osm_qos_options_t dflt;
+
if (p_opts->lmc > 7) {
log_report(" Invalid Cached Option Value:lmc = %u:"
"Using Default:%u\n", p_opts->lmc, OSM_DEFAULT_LMC);
@@ -1087,17 +1089,15 @@ int osm_subn_verify_config(IN osm_subn_opt_t * p_opts)
p_opts->console = OSM_DEFAULT_CONSOLE;
}
- if (p_opts->qos) {
- osm_qos_options_t dflt;
-
- /* the default options in qos_options must be correct.
- * every other one need not be, b/c those will default
- * back to whatever is in qos_options.
- */
- subn_set_default_qos_options(&dflt);
+ /* the default options in qos_options must be correct.
+ * every other one need not be, b/c those will default
+ * back to whatever is in qos_options.
+ */
+ subn_set_default_qos_options(&dflt);
+ subn_verify_qos_set(&p_opts->qos_options, "qos", &dflt);
- subn_verify_qos_set(&p_opts->qos_options, "qos", &dflt);
+ if (p_opts->qos) {
subn_verify_qos_set(&p_opts->qos_ca_options, "qos_ca",
&p_opts->qos_options);
subn_verify_qos_set(&p_opts->qos_sw0_options, "qos_sw0",
@@ -298,6 +298,7 @@ struct torus {
#define Z_MESH (1U << 2)
#define MSG_DEADLOCK (1U << 29)
#define NOTIFY_CHANGES (1U << 30)
+#define QOS_ENABLED (1U << 31)
#define ALL_MESH(flags) \
((flags & (X_MESH | Y_MESH | Z_MESH)) == (X_MESH | Y_MESH | Z_MESH))
@@ -8548,7 +8549,25 @@ uint8_t torus_path_sl(void *context, uint8_t path_sl_hint,
sl = sl_set_use_loop_vl(use_vl1(ssw->i, dsw->i, t->x_sz), 0);
sl |= sl_set_use_loop_vl(use_vl1(ssw->j, dsw->j, t->y_sz), 1);
sl |= sl_set_use_loop_vl(use_vl1(ssw->k, dsw->k, t->z_sz), 2);
- sl |= sl_set_qos(sl_get_qos(path_sl_hint));
+
+ /*
+ * If QoS was not requested by user, force path SLs into 8-15 range.
+ * This leaves SL 0 available for multicast, and SL2VL mappings
+ * will keep multicast traffic from deadlocking with unicast traffic.
+ *
+ * However, multicast might still deadlock against itself if multiple
+ * multicast groups each use their own spanning tree.
+ *
+ * FIXME: it is possible to construct a spanning tree that can
+ * overlay the DOR routing used for unicast in a way that multicast
+ * and unicast can share VLs but cannot deadlock against each other.
+ * Need to implement that and cause it to be used whenever the
+ * torus-2QoS routing engine is used.
+ */
+ if (t->flags & QOS_ENABLED)
+ sl |= sl_set_qos(sl_get_qos(path_sl_hint));
+ else
+ sl |= sl_set_qos(1);
out:
return sl;
}
@@ -8570,6 +8589,9 @@ int torus_build_lfts(void *context)
"Error: allocating torus: %s\n", strerror(errno));
goto out;
}
+ if (ctx->osm->subn.opt.qos)
+ torus->flags |= QOS_ENABLED;
+
torus->osm = ctx->osm;
fabric->osm = ctx->osm;