int osm_ucast_cache_process(osm_ucast_mgr_t * p_mgr)
{
	cl_qmap_t *tbl = &p_mgr->p_subn->sw_guid_tbl;
	cl_map_item_t *item;
	osm_switch_t *p_sw;
	uint16_t lft_size;

	if (!p_mgr->p_subn->opt.use_ucast_cache)
		return 1;

	ucast_cache_validate(p_mgr);
	if (!p_mgr->cache_valid)
		return 1;

	OSM_LOG(p_mgr->p_log, OSM_LOG_INFO,
		"Configuring switch tables using cached routing\n");

	for (item = cl_qmap_head(tbl); item != cl_qmap_end(tbl);
	     item = cl_qmap_next(item)) {
		p_sw = (osm_switch_t *) item;

		if (p_sw->need_update) {
			if (!p_sw->new_lft)
				/* no new routing was recently calculated for this
				   switch, but the LFT needs to be updated anyway */
				p_sw->new_lft = p_sw->lft;

			lft_size = (p_sw->max_lid_ho / IB_SMP_DATA_SIZE + 1)
				   * IB_SMP_DATA_SIZE;
			p_sw->lft = malloc(lft_size);
			if (!p_sw->lft)
				return IB_INSUFFICIENT_MEMORY;
			p_sw->lft_size = lft_size;
			memset(p_sw->lft, OSM_NO_PATH, p_sw->lft_size);
		}

	}

	osm_ucast_mgr_set_fwd_tables(p_mgr);

	return 0;
}
Exemplo n.º 2
0
static int ucast_mgr_route(struct osm_routing_engine *r, osm_opensm_t * osm)
{
	int ret;

	OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
		"building routing with \'%s\' routing algorithm...\n", r->name);

	/* Set the before each lft build to keep the routes in place between sweeps */
	if (osm->subn.opt.scatter_ports)
		srandom(osm->subn.opt.scatter_ports);

	if (!r->build_lid_matrices ||
	    (ret = r->build_lid_matrices(r->context)) > 0)
		ret = osm_ucast_mgr_build_lid_matrices(&osm->sm.ucast_mgr);

	if (ret < 0) {
		OSM_LOG(&osm->log, OSM_LOG_ERROR,
			"%s: cannot build lid matrices\n", r->name);
		return ret;
	}

	if (!r->ucast_build_fwd_tables ||
	    (ret = r->ucast_build_fwd_tables(r->context)) > 0)
		ret = ucast_mgr_build_lfts(&osm->sm.ucast_mgr);

	if (ret < 0) {
		OSM_LOG(&osm->log, OSM_LOG_ERROR,
			"%s: cannot build fwd tables\n", r->name);
		return ret;
	}

	osm->routing_engine_used = r;

	osm_ucast_mgr_set_fwd_tables(&osm->sm.ucast_mgr);

	return 0;
}
Exemplo n.º 3
0
int osm_ucast_mgr_process(IN osm_ucast_mgr_t * p_mgr)
{
	osm_opensm_t *p_osm;
	struct osm_routing_engine *p_routing_eng;
	cl_qmap_t *p_sw_guid_tbl;
	int failed = 0;

	OSM_LOG_ENTER(p_mgr->p_log);

	p_sw_guid_tbl = &p_mgr->p_subn->sw_guid_tbl;
	p_osm = p_mgr->p_subn->p_osm;
	p_routing_eng = p_osm->routing_engine_list;

	CL_PLOCK_EXCL_ACQUIRE(p_mgr->p_lock);

	/*
	   If there are no switches in the subnet, we are done.
	 */
	if (cl_qmap_count(p_sw_guid_tbl) == 0 ||
	    ucast_mgr_setup_all_switches(p_mgr->p_subn) < 0)
		goto Exit;

	failed = -1;
	p_osm->routing_engine_used = NULL;
	while (p_routing_eng) {
		failed = ucast_mgr_route(p_routing_eng, p_osm);
		if (!failed)
			break;
		p_routing_eng = p_routing_eng->next;
	}

	if (!p_osm->routing_engine_used &&
	    p_osm->no_fallback_routing_engine != TRUE) {
		/* If configured routing algorithm failed, use default MinHop */
		struct osm_routing_engine *r = p_osm->default_routing_engine;

		r->build_lid_matrices(r->context);
		failed = r->ucast_build_fwd_tables(r->context);
		if (!failed) {
			p_osm->routing_engine_used = r;
			osm_ucast_mgr_set_fwd_tables(p_mgr);
		}
	}

	if (p_osm->routing_engine_used) {
		OSM_LOG(p_mgr->p_log, OSM_LOG_INFO,
			"%s tables configured on all switches\n",
			osm_routing_engine_type_str(p_osm->
						    routing_engine_used->type));

		if (p_mgr->p_subn->opt.use_ucast_cache)
			p_mgr->cache_valid = TRUE;
	} else {
		p_mgr->p_subn->subnet_initialization_error = TRUE;
		OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
			"No routing engine able to successfully configure "
			" switch tables on current fabric\n");
	}
Exit:
	CL_PLOCK_RELEASE(p_mgr->p_lock);
	OSM_LOG_EXIT(p_mgr->p_log);
	return failed;
}