/********************************************************************** Add each switch's own and neighbor LIDs to its LID matrix **********************************************************************/ static void __osm_ucast_mgr_process_hop_0_1(IN cl_map_item_t * const p_map_item, IN void *context) { osm_switch_t *const p_sw = (osm_switch_t *) p_map_item; osm_node_t *p_remote_node; uint16_t lid, remote_lid; uint8_t i, remote_port; lid = osm_node_get_base_lid(p_sw->p_node, 0); lid = cl_ntoh16(lid); osm_switch_set_hops(p_sw, lid, 0, 0); for (i = 1; i < p_sw->num_ports; i++) { p_remote_node = osm_node_get_remote_node(p_sw->p_node, i, &remote_port); if (p_remote_node && p_remote_node->sw && (p_remote_node != p_sw->p_node)) { remote_lid = osm_node_get_base_lid(p_remote_node, 0); remote_lid = cl_ntoh16(remote_lid); osm_switch_set_hops(p_sw, remote_lid, i, 1); osm_switch_set_hops(p_remote_node->sw, lid, remote_port, 1); } } }
static void add_lid_hops(osm_opensm_t * p_osm, osm_switch_t * p_sw, uint16_t lid, ib_net64_t guid, uint8_t hops[], unsigned len) { uint16_t new_lid; uint8_t i; new_lid = guid ? remap_lid(p_osm, lid, guid) : lid; if (len > p_sw->num_ports) len = p_sw->num_ports; for (i = 0; i < len; i++) osm_switch_set_hops(p_sw, lid, i, hops[i]); }
/********************************************************************** Add each switch's own and neighbor LIDs to its LID matrix **********************************************************************/ static void ucast_mgr_process_hop_0_1(IN cl_map_item_t * p_map_item, IN void *context) { osm_switch_t * p_sw = (osm_switch_t *) p_map_item; osm_node_t *p_remote_node; uint16_t lid, remote_lid; uint8_t i; lid = cl_ntoh16(osm_node_get_base_lid(p_sw->p_node, 0)); osm_switch_set_hops(p_sw, lid, 0, 0); for (i = 1; i < p_sw->num_ports; i++) { osm_physp_t *p = osm_node_get_physp_ptr(p_sw->p_node, i); p_remote_node = (p && p->p_remote_physp) ? p->p_remote_physp->p_node : NULL; if (p_remote_node && p_remote_node->sw && p_remote_node != p_sw->p_node) { remote_lid = osm_node_get_base_lid(p_remote_node, 0); remote_lid = cl_ntoh16(remote_lid); osm_switch_set_hops(p_sw, remote_lid, i, p->hop_wf); } } }
static void ucast_mgr_process_neighbor(IN osm_ucast_mgr_t * p_mgr, IN osm_switch_t * p_this_sw, IN osm_switch_t * p_remote_sw, IN uint8_t port_num, IN uint8_t remote_port_num) { osm_switch_t *p_sw; cl_map_item_t *item; uint16_t lid_ho; uint16_t hops; osm_physp_t *p; OSM_LOG_ENTER(p_mgr->p_log); OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Node 0x%" PRIx64 ", remote node 0x%" PRIx64 ", port %u, remote port %u\n", cl_ntoh64(osm_node_get_node_guid(p_this_sw->p_node)), cl_ntoh64(osm_node_get_node_guid(p_remote_sw->p_node)), port_num, remote_port_num); p = osm_node_get_physp_ptr(p_this_sw->p_node, port_num); for (item = cl_qmap_head(&p_mgr->p_subn->sw_guid_tbl); item != cl_qmap_end(&p_mgr->p_subn->sw_guid_tbl); item = cl_qmap_next(item)) { p_sw = (osm_switch_t *) item; lid_ho = cl_ntoh16(osm_node_get_base_lid(p_sw->p_node, 0)); hops = osm_switch_get_least_hops(p_remote_sw, lid_ho); if (hops == OSM_NO_PATH) continue; hops += p->hop_wf; if (hops < osm_switch_get_hop_count(p_this_sw, lid_ho, port_num)) { if (osm_switch_set_hops (p_this_sw, lid_ho, port_num, (uint8_t) hops) != 0) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A03: " "cannot set hops for lid %u at switch 0x%" PRIx64 "\n", lid_ho, cl_ntoh64(osm_node_get_node_guid (p_this_sw->p_node))); p_mgr->some_hop_count_set = TRUE; } } OSM_LOG_EXIT(p_mgr->p_log); }
static void __osm_ucast_mgr_process_neighbor(IN osm_ucast_mgr_t * const p_mgr, IN osm_switch_t * const p_this_sw, IN osm_switch_t * const p_remote_sw, IN const uint8_t port_num, IN const uint8_t remote_port_num) { osm_switch_t *p_sw, *p_next_sw; uint16_t lid_ho; uint8_t hops; OSM_LOG_ENTER(p_mgr->p_log); OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Node 0x%" PRIx64 ", remote node 0x%" PRIx64 ", port %u, remote port %u\n", cl_ntoh64(osm_node_get_node_guid(p_this_sw->p_node)), cl_ntoh64(osm_node_get_node_guid(p_remote_sw->p_node)), port_num, remote_port_num); p_next_sw = (osm_switch_t *) cl_qmap_head(&p_mgr->p_subn->sw_guid_tbl); while (p_next_sw != (osm_switch_t *) cl_qmap_end(&p_mgr->p_subn->sw_guid_tbl)) { p_sw = p_next_sw; p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item); lid_ho = osm_node_get_base_lid(p_sw->p_node, 0); lid_ho = cl_ntoh16(lid_ho); hops = osm_switch_get_least_hops(p_remote_sw, lid_ho); if (hops == OSM_NO_PATH) continue; hops++; if (hops < osm_switch_get_hop_count(p_this_sw, lid_ho, port_num)) { if (osm_switch_set_hops (p_this_sw, lid_ho, port_num, hops) != 0) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "cannot set hops for lid %u at switch 0x%" PRIx64 "\n", lid_ho, cl_ntoh64(osm_node_get_node_guid (p_this_sw->p_node))); p_mgr->some_hop_count_set = TRUE; } } OSM_LOG_EXIT(p_mgr->p_log); }
/********************************************************************** * This function does the bfs of min hop table calculation by guid index * as a starting point. **********************************************************************/ static int updn_bfs_by_node(IN osm_log_t * p_log, IN osm_subn_t * p_subn, IN osm_switch_t * p_sw) { uint8_t pn, pn_rem; cl_qlist_t list; uint16_t lid; struct updn_node *u; updn_switch_dir_t next_dir, current_dir; OSM_LOG_ENTER(p_log); lid = osm_node_get_base_lid(p_sw->p_node, 0); lid = cl_ntoh16(lid); osm_switch_set_hops(p_sw, lid, 0, 0); OSM_LOG(p_log, OSM_LOG_DEBUG, "Starting from switch - port GUID 0x%" PRIx64 " lid %u\n", cl_ntoh64(p_sw->p_node->node_info.port_guid), lid); u = p_sw->priv; u->dir = UP; /* Update list with the new element */ cl_qlist_init(&list); cl_qlist_insert_tail(&list, &u->list); /* BFS the list till no next element */ while (!cl_is_qlist_empty(&list)) { u = (struct updn_node *)cl_qlist_remove_head(&list); u->visited = 0; /* cleanup */ current_dir = u->dir; /* Go over all ports of the switch and find unvisited remote nodes */ for (pn = 1; pn < u->sw->num_ports; pn++) { osm_node_t *p_remote_node; struct updn_node *rem_u; uint8_t current_min_hop, remote_min_hop, set_hop_return_value; osm_switch_t *p_remote_sw; p_remote_node = osm_node_get_remote_node(u->sw->p_node, pn, &pn_rem); /* If no remote node OR remote node is not a SWITCH continue to next pn */ if (!p_remote_node || !p_remote_node->sw) continue; /* Fetch remote guid only after validation of remote node */ p_remote_sw = p_remote_node->sw; rem_u = p_remote_sw->priv; /* Decide which direction to mark it (UP/DOWN) */ next_dir = updn_get_dir(u->rank, rem_u->rank, u->id, rem_u->id); /* Check if this is a legal step : the only illegal step is going from DOWN to UP */ if ((current_dir == DOWN) && (next_dir == UP)) { OSM_LOG(p_log, OSM_LOG_DEBUG, "Avoiding move from 0x%016" PRIx64 " to 0x%016" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(u->sw->p_node)), cl_ntoh64(osm_node_get_node_guid(p_remote_node))); /* Illegal step */ continue; } /* Set MinHop value for the current lid */ current_min_hop = osm_switch_get_least_hops(u->sw, lid); /* Check hop count if better insert into list && update the remote node Min Hop Table */ remote_min_hop = osm_switch_get_hop_count(p_remote_sw, lid, pn_rem); if (current_min_hop + 1 < remote_min_hop) { set_hop_return_value = osm_switch_set_hops(p_remote_sw, lid, pn_rem, current_min_hop + 1); if (set_hop_return_value) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AA01: " "Invalid value returned from set min hop is: %d\n", set_hop_return_value); } /* Check if remote port has already been visited */ if (!rem_u->visited) { /* Insert updn_switch item into the list */ rem_u->dir = next_dir; rem_u->visited = 1; cl_qlist_insert_tail(&list, &rem_u->list); } } } } OSM_LOG_EXIT(p_log); return 0; }