static void ucast_cache_dump(osm_ucast_mgr_t * p_mgr) { cache_switch_t *p_sw; unsigned i; OSM_LOG_ENTER(p_mgr->p_log); if (!OSM_LOG_IS_ACTIVE_V2(p_mgr->p_log, OSM_LOG_DEBUG)) goto Exit; OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Dumping missing nodes/links as logged by unicast cache:\n"); for (p_sw = (cache_switch_t *) cl_qmap_head(&p_mgr->cache_sw_tbl); p_sw != (cache_switch_t *) cl_qmap_end(&p_mgr->cache_sw_tbl); p_sw = (cache_switch_t *) cl_qmap_next(&p_sw->map_item)) { OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "\t Switch lid %u %s%s\n", cache_sw_get_base_lid_ho(p_sw), (cache_sw_is_leaf(p_sw)) ? "[leaf switch] " : "", (p_sw->dropped) ? "[whole switch missing]" : ""); for (i = 1; i < p_sw->num_ports; i++) if (p_sw->ports[i].remote_lid_ho > 0) OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "\t - port %u -> lid %u %s\n", i, p_sw->ports[i].remote_lid_ho, (p_sw->ports[i].is_leaf) ? "[remote node is leaf]" : ""); } Exit: OSM_LOG_EXIT(p_mgr->p_log); }
void osm_dump_mcast_routes(osm_opensm_t * osm) { if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_ROUTING)) /* multicast routes */ osm_dump_qmap_to_file(osm, "opensm.mcfdbs", &osm->subn.sw_guid_tbl, dump_mcast_routes, osm); }
void osm_dump_all(osm_opensm_t * osm) { if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_ROUTING)) { /* unicast routes */ osm_dump_qmap_to_file(osm, "opensm-lid-matrix.dump", &osm->subn.sw_guid_tbl, dump_lid_matrix, osm); osm_dump_qmap_to_file(osm, "opensm-lfts.dump", &osm->subn.sw_guid_tbl, dump_ucast_lfts, osm); if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_DEBUG)) dump_qmap(stdout, &osm->subn.sw_guid_tbl, dump_ucast_path_distribution, osm); /* An attempt to get osm_switch_recommend_path to report the same routes that a sweep would assign. */ if (osm->subn.opt.scatter_ports) srandom(osm->subn.opt.scatter_ports); osm_dump_qmap_to_file(osm, "opensm.fdbs", &osm->subn.sw_guid_tbl, dump_ucast_routes, osm); /* multicast routes */ osm_dump_qmap_to_file(osm, "opensm.mcfdbs", &osm->subn.sw_guid_tbl, dump_mcast_routes, osm); /* SL2VL tables */ if (osm->subn.opt.qos || (osm->routing_engine_used && osm->routing_engine_used->update_sl2vl)) osm_dump_qmap_to_file(osm, "opensm-sl2vl.dump", &osm->subn.port_guid_tbl, dump_sl2vl_tbl, osm); } osm_dump_qmap_to_file(osm, "opensm-subnet.lst", &osm->subn.node_guid_tbl, dump_topology_node, osm); if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_VERBOSE)) print_report(osm, stdout); }
static inline void debug_dump_dc_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num, db_port_t * port, perfmgr_db_data_cnt_reading_t * cur) { osm_log_t *log = db->perfmgr->log; if (!OSM_LOG_IS_ACTIVE_V2(log, OSM_LOG_DEBUG)) return; osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "xd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->xmit_data, port->dc_previous.xmit_data, port->dc_total.xmit_data); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "rd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_data, port->dc_previous.rcv_data, port->dc_total.rcv_data); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "xp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->xmit_pkts, port->dc_previous.xmit_pkts, port->dc_total.xmit_pkts); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "rp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_pkts, port->dc_previous.rcv_pkts, port->dc_total.rcv_pkts); }
void osm_mpr_rcv_process(IN void *context, IN void *data) { osm_sa_t *sa = context; osm_madw_t *p_madw = data; const ib_multipath_rec_t *p_mpr; ib_sa_mad_t *p_sa_mad; osm_port_t *requester_port; osm_alias_guid_t *pp_alias_guids[IB_MULTIPATH_MAX_GIDS]; cl_qlist_t pr_list; ib_net16_t sa_status; int nsrc, ndest; uint8_t rate, mtu; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_mpr = (ib_multipath_rec_t *) ib_sa_mad_get_payload_ptr(p_sa_mad); CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_MULTIPATH_RECORD); if ((p_sa_mad->rmpp_flags & IB_RMPP_FLAG_ACTIVE) != IB_RMPP_FLAG_ACTIVE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4510: " "Invalid request since RMPP_FLAG_ACTIVE is not set\n"); osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } /* we only support SubnAdmGetMulti method */ if (p_sa_mad->method != IB_MAD_METHOD_GETMULTI) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4513: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_sa_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (requester_port == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4517: " "Cannot find requester physical port\n"); goto Exit; } if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) { OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_port_get_guid(requester_port))); osm_dump_multipath_record_v2(sa->p_log, p_mpr, FILE_ID, OSM_LOG_DEBUG); } /* Make sure required components (S/DGIDCount) are supplied */ if (!(p_sa_mad->comp_mask & IB_MPR_COMPMASK_SGIDCOUNT) || !(p_sa_mad->comp_mask & IB_MPR_COMPMASK_DGIDCOUNT)) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_INSUF_COMPS); goto Exit; } /* Validate rate if supplied */ if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_RATESELEC) && (p_sa_mad->comp_mask & IB_MPR_COMPMASK_RATE)) { rate = ib_multipath_rec_rate(p_mpr); if (!ib_rate_is_valid(rate)) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } } /* Validate MTU if supplied */ if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_MTUSELEC) && (p_sa_mad->comp_mask & IB_MPR_COMPMASK_MTU)) { mtu = ib_multipath_rec_mtu(p_mpr); if (!ib_mtu_is_valid(mtu)) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } } /* Make sure either none or both ServiceID parameters are supplied */ if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_SERVICEID) != 0 && (p_sa_mad->comp_mask & IB_MPR_COMPMASK_SERVICEID) != IB_MPR_COMPMASK_SERVICEID) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_INSUF_COMPS); goto Exit; } cl_qlist_init(&pr_list); /* Most SA functions (including this one) are read-only on the subnet object, so we grab the lock non-exclusively. */ cl_plock_acquire(sa->p_lock); sa_status = mpr_rcv_get_end_points(sa, p_madw, pp_alias_guids, &nsrc, &ndest); if (sa_status != IB_SA_MAD_STATUS_SUCCESS || !nsrc || !ndest) { if (sa_status == IB_SA_MAD_STATUS_SUCCESS && (!nsrc || !ndest)) OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4512: " "mpr_rcv_get_end_points failed, # GIDs found; " "src %d; dest %d)\n", nsrc, ndest); cl_plock_release(sa->p_lock); if (sa_status == IB_SA_MAD_STATUS_SUCCESS) osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); else osm_sa_send_error(sa, p_madw, sa_status); goto Exit; } /* APM request */ if (nsrc == 2 && ndest == 2 && (p_mpr->num_path & 0x7F) == 2) mpr_rcv_get_apm_paths(sa, p_mpr, requester_port, pp_alias_guids, p_sa_mad->comp_mask, &pr_list); else mpr_rcv_process_pairs(sa, p_mpr, requester_port, pp_alias_guids, nsrc, ndest, p_sa_mad->comp_mask, &pr_list); cl_plock_release(sa->p_lock); /* o15-0.2.7: If MultiPath is supported, then SA shall respond to a SubnAdmGetMulti() containing a valid MultiPathRecord attribute with a set of zero or more PathRecords satisfying the constraints indicated in the MultiPathRecord received. The PathRecord Attribute ID shall be used in the response. */ p_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD; osm_sa_respond(sa, p_madw, sizeof(ib_path_rec_t), &pr_list); Exit: OSM_LOG_EXIT(sa->p_log); }
static void cpi_rcv_respond(IN osm_sa_t * sa, IN const osm_madw_t * p_madw) { osm_madw_t *p_resp_madw; const ib_sa_mad_t *p_sa_mad; ib_sa_mad_t *p_resp_sa_mad; ib_class_port_info_t *p_resp_cpi; ib_gid_t zero_gid; uint32_t cap_mask2; uint8_t rtv; OSM_LOG_ENTER(sa->p_log); memset(&zero_gid, 0, sizeof(ib_gid_t)); /* Get a MAD to reply. Address of Mad is in the received mad_wrapper */ p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind, MAD_BLOCK_SIZE, &p_madw->mad_addr); if (!p_resp_madw) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1408: " "Unable to allocate MAD\n"); goto Exit; } p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw); memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE); p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK; /* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */ p_resp_sa_mad->sm_key = 0; p_resp_cpi = (ib_class_port_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad); /* finally do it (the job) man ! */ p_resp_cpi->base_ver = 1; p_resp_cpi->class_ver = 2; /* Calculate encoded response time value */ /* transaction timeout is in msec */ if (sa->p_subn->opt.transaction_timeout > msecs_to_rtv_table[MAX_MSECS_TO_RTV - 1]) rtv = MAX_MSECS_TO_RTV - 1; else { for (rtv = 0; rtv < MAX_MSECS_TO_RTV; rtv++) { if (sa->p_subn->opt.transaction_timeout <= msecs_to_rtv_table[rtv]) break; } } rtv += 8; ib_class_set_resp_time_val(p_resp_cpi, rtv); p_resp_cpi->redir_gid = zero_gid; p_resp_cpi->redir_tc_sl_fl = 0; p_resp_cpi->redir_lid = 0; p_resp_cpi->redir_pkey = 0; p_resp_cpi->redir_qp = CL_NTOH32(1); p_resp_cpi->redir_qkey = IB_QP1_WELL_KNOWN_Q_KEY; p_resp_cpi->trap_gid = zero_gid; p_resp_cpi->trap_tc_sl_fl = 0; p_resp_cpi->trap_lid = 0; p_resp_cpi->trap_pkey = 0; p_resp_cpi->trap_hop_qp = 0; p_resp_cpi->trap_qkey = IB_QP1_WELL_KNOWN_Q_KEY; /* set specific capability mask bits */ /* we do not support the following options/optional records: OSM_CAP_IS_SUBN_OPT_RECS_SUP : RandomForwardingTableRecord, ServiceAssociationRecord other optional records supported "under the table" OSM_CAP_IS_MULTIPATH_SUP: TraceRecord OSM_CAP_IS_REINIT_SUP: For reinitialization functionality. So not sending traps, but supporting Get(Notice) and Set(Notice). */ /* Note host notation replaced later */ #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP) p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP | OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED | OSM_CAP_IS_MULTIPATH_SUP; #else p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP | OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED; #endif cap_mask2 = OSM_CAP2_IS_FULL_PORTINFO_REC_SUPPORTED | OSM_CAP2_IS_EXTENDED_SPEEDS_SUPPORTED | OSM_CAP2_IS_ALIAS_GUIDS_SUPPORTED | OSM_CAP2_IS_MULTICAST_SERVICE_RECS_SUPPORTED | OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED | OSM_CAP2_IS_LINK_WIDTH_2X_SUPPORTED; if (sa->p_subn->opt.use_mfttop) cap_mask2 |= OSM_CAP2_IS_MCAST_TOP_SUPPORTED; if (sa->p_subn->opt.qos) cap_mask2 |= OSM_CAP2_IS_QOS_SUPPORTED; ib_class_set_cap_mask2(p_resp_cpi, cap_mask2); if (!sa->p_subn->opt.disable_multicast) p_resp_cpi->cap_mask |= OSM_CAP_IS_UD_MCAST_SUP; p_resp_cpi->cap_mask = cl_hton16(p_resp_cpi->cap_mask); if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES)) osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES); osm_sa_send(sa, p_resp_madw, FALSE); Exit: OSM_LOG_EXIT(sa->p_log); }
void osm_smir_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *sad_mad; const ib_sminfo_record_t *p_rcvd_rec; const osm_port_t *p_port = NULL; const ib_sm_info_t *p_smi; cl_qlist_t rec_list; osm_smir_search_ctxt_t context; ib_api_status_t status = IB_SUCCESS; ib_net64_t comp_mask; ib_net64_t port_guid; osm_physp_t *p_req_physp; osm_port_t *local_port; osm_remote_sm_t *p_rem_sm; cl_qmap_t *p_sm_guid_tbl; uint8_t pri_state; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); sad_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_sminfo_record_t *) ib_sa_mad_get_payload_ptr(sad_mad); comp_mask = sad_mad->comp_mask; CL_ASSERT(sad_mad->attr_id == IB_MAD_ATTR_SMINFO_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (sad_mad->method != IB_MAD_METHOD_GET && sad_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2804: " "Unsupported Method (%s)\n", ib_get_sa_method_str(sad_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2803: " "Cannot find requester physical port\n"); goto Exit; } if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) { OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_req_physp))); osm_dump_sm_info_record_v2(sa->p_log, p_rcvd_rec, FILE_ID, OSM_LOG_DEBUG); } p_smi = &p_rcvd_rec->sm_info; cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = sad_mad->comp_mask; context.sa = sa; context.p_req_physp = p_req_physp; cl_plock_acquire(sa->p_lock); /* If the user specified a LID, it obviously narrows our work load, since we don't have to search every port */ if (comp_mask & IB_SMIR_COMPMASK_LID) { p_port = osm_get_port_by_lid(sa->p_subn, p_rcvd_rec->lid); if (!p_port) { status = IB_NOT_FOUND; OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2806: " "No port found with LID %u\n", cl_ntoh16(p_rcvd_rec->lid)); } } if (status == IB_SUCCESS) { /* Handle our own SM first */ local_port = osm_get_port_by_guid(sa->p_subn, sa->p_subn->sm_port_guid); if (!local_port) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2809: " "No port found with GUID 0x%016" PRIx64 "\n", cl_ntoh64(sa->p_subn->sm_port_guid)); goto Exit; } if (!p_port || local_port == p_port) { if (FALSE == osm_physp_share_pkey(sa->p_log, p_req_physp, local_port->p_physp, sa->p_subn->opt.allow_both_pkeys)) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2805: " "Cannot get SMInfo record due to pkey violation\n"); goto Exit; } /* Check that other search components specified match */ if ((comp_mask & IB_SMIR_COMPMASK_GUID) && sa->p_subn->sm_port_guid != p_smi->guid) goto Remotes; if ((comp_mask & IB_SMIR_COMPMASK_PRIORITY) && sa->p_subn->opt.sm_priority != ib_sminfo_get_priority(p_smi)) goto Remotes; if ((comp_mask & IB_SMIR_COMPMASK_SMSTATE) && sa->p_subn->sm_state != ib_sminfo_get_state(p_smi)) goto Remotes; /* Now, add local SMInfo to list */ pri_state = sa->p_subn->sm_state & 0x0F; pri_state |= (sa->p_subn->opt.sm_priority & 0x0F) << 4; smir_rcv_new_smir(sa, local_port, context.p_list, sa->p_subn->sm_port_guid, cl_ntoh32(sa->p_subn->p_osm->stats. qp0_mads_sent), pri_state, p_req_physp); } Remotes: if (p_port && p_port != local_port) { /* Find remote SM corresponding to p_port */ port_guid = osm_port_get_guid(p_port); p_sm_guid_tbl = &sa->p_subn->sm_guid_tbl; p_rem_sm = (osm_remote_sm_t *) cl_qmap_get(p_sm_guid_tbl, port_guid); if (p_rem_sm != (osm_remote_sm_t *) cl_qmap_end(p_sm_guid_tbl)) sa_smir_by_comp_mask(sa, p_rem_sm, &context); else OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 280A: " "No remote SM for GUID 0x%016" PRIx64 "\n", cl_ntoh64(port_guid)); } else { /* Go over all other known (remote) SMs */ cl_qmap_apply_func(&sa->p_subn->sm_guid_tbl, sa_smir_by_comp_mask_cb, &context); } } cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_sminfo_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
/********************************************************************** * Dump a reading vs the previous reading to stdout **********************************************************************/ static inline void debug_dump_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num, db_port_t * port, perfmgr_db_err_reading_t * cur) { osm_log_t *log = db->perfmgr->log; if (!OSM_LOG_IS_ACTIVE_V2(log, OSM_LOG_DEBUG)) return; /* optimize this a bit */ osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "GUID 0x%" PRIx64 " Port %u:\n", guid, port_num); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "sym %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->symbol_err_cnt, port->err_previous.symbol_err_cnt, port->err_total.symbol_err_cnt); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "ler %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->link_err_recover, port->err_previous.link_err_recover, port->err_total.link_err_recover); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "ld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->link_downed, port->err_previous.link_downed, port->err_total.link_downed); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "re %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_err, port->err_previous.rcv_err, port->err_total.rcv_err); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "rrp %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_rem_phys_err, port->err_previous.rcv_rem_phys_err, port->err_total.rcv_rem_phys_err); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "rsr %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_switch_relay_err, port->err_previous.rcv_switch_relay_err, port->err_total.rcv_switch_relay_err); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "xd %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->xmit_discards, port->err_previous.xmit_discards, port->err_total.xmit_discards); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "xce %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->xmit_constraint_err, port->err_previous.xmit_constraint_err, port->err_total.xmit_constraint_err); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "rce %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->rcv_constraint_err, port->err_previous.rcv_constraint_err, port->err_total.rcv_constraint_err); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "li %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->link_integrity, port->err_previous.link_integrity, port->err_total.link_integrity); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "bo %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->buffer_overrun, port->err_previous.buffer_overrun, port->err_total.buffer_overrun); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "vld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->vl15_dropped, port->err_previous.vl15_dropped, port->err_total.vl15_dropped); osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID, "xw %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n", cur->xmit_wait, port->err_previous.xmit_wait, port->err_total.xmit_wait); }
void osm_lr_rcv_process(IN void *context, IN void *data) { osm_sa_t *sa = context; osm_madw_t *p_madw = data; const ib_link_record_t *p_lr; const ib_sa_mad_t *p_sa_mad; const osm_port_t *p_src_port; const osm_port_t *p_dest_port; cl_qlist_t lr_list; ib_net16_t status; osm_physp_t *p_req_physp; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_lr = ib_sa_mad_get_payload_ptr(p_sa_mad); CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_LINK_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_sa_mad->method != IB_MAD_METHOD_GET && p_sa_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1804: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_sa_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1805: " "Cannot find requester physical port\n"); goto Exit; } if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) { OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_req_physp))); osm_dump_link_record_v2(sa->p_log, p_lr, FILE_ID, OSM_LOG_DEBUG); } cl_qlist_init(&lr_list); /* Most SA functions (including this one) are read-only on the subnet object, so we grab the lock non-exclusively. */ cl_plock_acquire(sa->p_lock); status = lr_rcv_get_end_points(sa, p_madw, &p_src_port, &p_dest_port); if (status == IB_SA_MAD_STATUS_SUCCESS) lr_rcv_get_port_links(sa, p_lr, p_src_port, p_dest_port, p_sa_mad->comp_mask, &lr_list, p_req_physp); cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_link_record_t), &lr_list); Exit: OSM_LOG_EXIT(sa->p_log); }
/* UPDN callback function */ static int updn_lid_matrices(void *ctx) { updn_t *p_updn = ctx; cl_map_item_t *item; osm_switch_t *p_sw; int ret = 0; OSM_LOG_ENTER(&p_updn->p_osm->log); for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl); item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl); item = cl_qmap_next(item)) { p_sw = (osm_switch_t *)item; p_sw->priv = create_updn_node(p_sw); if (!p_sw->priv) { OSM_LOG(&(p_updn->p_osm->log), OSM_LOG_ERROR, "ERR AA0C: " "cannot create updn node\n"); OSM_LOG_EXIT(&p_updn->p_osm->log); return -1; } } /* First setup root nodes */ p_updn->num_roots = 0; if (p_updn->p_osm->subn.opt.root_guid_file) { OSM_LOG(&p_updn->p_osm->log, OSM_LOG_DEBUG, "UPDN - Fetching root nodes from file \'%s\'\n", p_updn->p_osm->subn.opt.root_guid_file); ret = parse_node_map(p_updn->p_osm->subn.opt.root_guid_file, rank_root_node, p_updn); if (ret) { OSM_LOG(&p_updn->p_osm->log, OSM_LOG_ERROR, "ERR AA02: " "cannot parse root guids file \'%s\'\n", p_updn->p_osm->subn.opt.root_guid_file); osm_ucast_mgr_build_lid_matrices(&p_updn->p_osm->sm.ucast_mgr); updn_find_root_nodes_by_min_hop(p_updn); } else if (p_updn->p_osm->subn.opt.connect_roots && p_updn->num_roots > 1) osm_ucast_mgr_build_lid_matrices(&p_updn->p_osm->sm.ucast_mgr); } else { osm_ucast_mgr_build_lid_matrices(&p_updn->p_osm->sm.ucast_mgr); updn_find_root_nodes_by_min_hop(p_updn); } if (p_updn->p_osm->subn.opt.ids_guid_file) { OSM_LOG(&p_updn->p_osm->log, OSM_LOG_DEBUG, "UPDN - update node ids from file \'%s\'\n", p_updn->p_osm->subn.opt.ids_guid_file); ret = parse_node_map(p_updn->p_osm->subn.opt.ids_guid_file, update_id, p_updn->p_osm); if (ret) OSM_LOG(&p_updn->p_osm->log, OSM_LOG_ERROR, "ERR AA03: " "cannot parse node ids file \'%s\'\n", p_updn->p_osm->subn.opt.ids_guid_file); } /* Only if there are assigned root nodes do the algorithm, otherwise perform do nothing */ if (p_updn->num_roots) { OSM_LOG(&p_updn->p_osm->log, OSM_LOG_DEBUG, "activating UPDN algorithm\n"); ret = updn_build_lid_matrices(p_updn); } else { OSM_LOG(&p_updn->p_osm->log, OSM_LOG_INFO, "disabling UPDN algorithm, no root nodes were found\n"); ret = -1; } if (OSM_LOG_IS_ACTIVE_V2(&p_updn->p_osm->log, OSM_LOG_ROUTING)) osm_dump_qmap_to_file(p_updn->p_osm, "opensm-updn-roots.dump", &p_updn->p_osm->subn.sw_guid_tbl, dump_roots, NULL); for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl); item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl); item = cl_qmap_next(item)) { p_sw = (osm_switch_t *) item; delete_updn_node(p_sw->priv); } OSM_LOG_EXIT(&p_updn->p_osm->log); return ret; }
static void do_sweep(osm_sm_t * sm) { ib_api_status_t status; osm_remote_sm_t *p_remote_sm; unsigned config_parsed = 0; if (sm->p_subn->force_heavy_sweep) { if (osm_subn_rescan_conf_files(sm->p_subn) < 0) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 331A: " "osm_subn_rescan_conf_file failed\n"); else config_parsed = 1; } if (sm->p_subn->sm_state != IB_SMINFO_STATE_MASTER && sm->p_subn->sm_state != IB_SMINFO_STATE_DISCOVERING) return; if (sm->p_subn->coming_out_of_standby) { /* * Need to force re-write of sm_base_lid to all ports * to do that we want all the ports to be considered * foreign */ state_mgr_clean_known_lids(sm); /* * Need to reconfigure LFTs, PKEYs, and QoS on all switches * when coming out of STANDBY */ sm->p_subn->need_update = 1; } sm->master_sm_found = 0; /* * If we already have switches, then try a light sweep. * Otherwise, this is probably our first discovery pass * or we are connected in loopback. In both cases do a * heavy sweep. * Note: If we are connected in loopback we want a heavy * sweep, since we will not be getting any traps if there is * a lost connection. */ /* if we are in DISCOVERING state - this means it is either in * initializing or wake up from STANDBY - run the heavy sweep */ if (cl_qmap_count(&sm->p_subn->sw_guid_tbl) && sm->p_subn->sm_state != IB_SMINFO_STATE_DISCOVERING && sm->p_subn->opt.force_heavy_sweep == FALSE && sm->p_subn->force_heavy_sweep == FALSE && sm->p_subn->force_reroute == FALSE && sm->p_subn->subnet_initialization_error == FALSE && (state_mgr_light_sweep_start(sm) == IB_SUCCESS)) { if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; if (!sm->p_subn->force_heavy_sweep) { if (sm->p_subn->opt.sa_db_dump && !osm_sa_db_file_dump(sm->p_subn->p_osm)) osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_SA_DB_DUMPED, NULL); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "LIGHT SWEEP COMPLETE"); return; } } /* * Unicast cache should be invalidated if there were errors * during initialization or if subnet re-route is requested. */ if (sm->p_subn->opt.use_ucast_cache && (sm->p_subn->subnet_initialization_error || sm->p_subn->force_reroute || sm->p_subn->coming_out_of_standby)) osm_ucast_cache_invalidate(&sm->ucast_mgr); /* * If we don't need to do a heavy sweep and we want to do a reroute, * just reroute only. */ if (cl_qmap_count(&sm->p_subn->sw_guid_tbl) && sm->p_subn->sm_state != IB_SMINFO_STATE_DISCOVERING && sm->p_subn->opt.force_heavy_sweep == FALSE && sm->p_subn->force_heavy_sweep == FALSE && sm->p_subn->force_reroute == TRUE && sm->p_subn->subnet_initialization_error == FALSE) { /* Reset flag */ sm->p_subn->force_reroute = FALSE; /* Re-program the switches fully */ sm->p_subn->ignore_existing_lfts = TRUE; if (osm_ucast_mgr_process(&sm->ucast_mgr)) { OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "REROUTE FAILED"); return; } osm_qos_setup(sm->p_subn->p_osm); /* Reset flag */ sm->p_subn->ignore_existing_lfts = FALSE; if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; osm_congestion_control_setup(sm->p_subn->p_osm); if (osm_congestion_control_wait_pending_transactions (sm->p_subn->p_osm)) return; if (!sm->p_subn->subnet_initialization_error) { OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "REROUTE COMPLETE"); osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_UCAST_ROUTING_DONE, NULL); return; } } osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_HEAVY_SWEEP_START, NULL); /* go to heavy sweep */ repeat_discovery: /* First of all - unset all flags */ sm->p_subn->force_heavy_sweep = FALSE; sm->p_subn->force_reroute = FALSE; sm->p_subn->subnet_initialization_error = FALSE; /* Reset tracking values in case limiting component got removed * from fabric. */ sm->p_subn->min_ca_mtu = IB_MAX_MTU; sm->p_subn->min_ca_rate = IB_MAX_RATE; sm->p_subn->min_data_vls = IB_MAX_NUM_VLS - 1; /* rescan configuration updates */ if (!config_parsed && osm_subn_rescan_conf_files(sm->p_subn) < 0) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 331A: " "osm_subn_rescan_conf_file failed\n"); if (sm->p_subn->sm_state != IB_SMINFO_STATE_MASTER) sm->p_subn->need_update = 1; status = state_mgr_sweep_hop_0(sm); if (status != IB_SUCCESS || wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; if (state_mgr_is_sm_port_down(sm) == TRUE) { if (sm->p_subn->last_sm_port_state) { sm->p_subn->last_sm_port_state = 0; osm_log_v2(sm->p_log, OSM_LOG_SYS, FILE_ID, "SM port is down\n"); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "SM PORT DOWN"); } /* Run the drop manager - we want to clear all records */ osm_drop_mgr_process(sm); /* Move to DISCOVERING state */ if (sm->p_subn->sm_state != IB_SMINFO_STATE_DISCOVERING) osm_sm_state_mgr_process(sm, OSM_SM_SIGNAL_DISCOVER); osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_STATE_CHANGE, NULL); return; } else { if (!sm->p_subn->last_sm_port_state) { sm->p_subn->last_sm_port_state = 1; osm_log_v2(sm->p_log, OSM_LOG_SYS, FILE_ID, "SM port is up\n"); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "SM PORT UP"); } } status = state_mgr_sweep_hop_1(sm); if (status != IB_SUCCESS || wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; /* discovery completed - check other sm presence */ if (sm->master_sm_found) { /* * Call the sm_state_mgr with signal * MASTER_OR_HIGHER_SM_DETECTED_DONE */ osm_sm_state_mgr_process(sm, OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "ENTERING STANDBY STATE"); /* notify master SM about us */ osm_send_trap144(sm, 0); osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_STATE_CHANGE, NULL); return; } /* if new sweep requested - don't bother with the rest */ if (sm->p_subn->force_heavy_sweep) { config_parsed = 0; goto repeat_discovery; } osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_HEAVY_SWEEP_DONE, NULL); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "HEAVY SWEEP COMPLETE"); osm_drop_mgr_process(sm); /* If we are MASTER - get the highest remote_sm, and * see if it is higher than our local sm. */ if (sm->p_subn->sm_state == IB_SMINFO_STATE_MASTER) { p_remote_sm = state_mgr_get_highest_sm(sm); if (p_remote_sm != NULL) { /* report new ports (trap 64) before leaving MASTER */ state_mgr_report_new_ports(sm); /* need to handover the mastership * to the remote sm, and move to standby */ state_mgr_send_handover(sm, p_remote_sm); osm_sm_state_mgr_process(sm, OSM_SM_SIGNAL_HANDOVER_SENT); return; } else { /* We are the highest sm - check to see if there is * a remote SM that is in master state. */ p_remote_sm = state_mgr_exists_other_master_sm(sm); if (p_remote_sm != NULL) { /* There is a remote SM that is master. * need to wait for that SM to relinquish control * of its portion of the subnet. C14-60.2.1. * Also - need to start polling on that SM. */ sm->p_polling_sm = p_remote_sm; osm_sm_state_mgr_process(sm, OSM_SM_SIGNAL_WAIT_FOR_HANDOVER); return; } } } /* * If we are not MASTER already - this means that we are * in discovery state. call osm_sm_state_mgr with signal * DISCOVERY_COMPLETED */ if (sm->p_subn->sm_state == IB_SMINFO_STATE_DISCOVERING) osm_sm_state_mgr_process(sm, OSM_SM_SIGNAL_DISCOVERY_COMPLETED); osm_pkey_mgr_process(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) */ osm_sa_db_file_load(sm->p_subn->p_osm); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "PKEY setup completed - STARTING SM LID CONFIG"); osm_lid_mgr_process_sm(&sm->lid_mgr); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "SM LID ASSIGNMENT COMPLETE - STARTING SUBNET LID CONFIG"); state_mgr_notify_lid_change(sm); osm_lid_mgr_process_subnet(&sm->lid_mgr); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; /* At this point we need to check the consistency of * the port_lid_tbl under the subnet. There might be * errors in it if PortInfo Set requests didn't reach * their destination. */ state_mgr_check_tbl_consistency(sm); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "LID ASSIGNMENT COMPLETE - STARTING SWITCH TABLE CONFIG"); /* * Proceed with unicast forwarding table configuration; if it fails * return early to wait for a trap or the next sweep interval. */ if (!sm->ucast_mgr.cache_valid || osm_ucast_cache_process(&sm->ucast_mgr)) if (osm_ucast_mgr_process(&sm->ucast_mgr)) return; osm_qos_setup(sm->p_subn->p_osm); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; /* cleanup switch lft buffers */ cl_qmap_apply_func(&sm->p_subn->sw_guid_tbl, cleanup_switch, sm->p_log); /* We are done setting all LFTs so clear the ignore existing. * From now on, as long as we are still master, we want to * take into account these lfts. */ sm->p_subn->ignore_existing_lfts = FALSE; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "SWITCHES CONFIGURED FOR UNICAST"); osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_UCAST_ROUTING_DONE, NULL); if (!sm->p_subn->opt.disable_multicast) { osm_mcast_mgr_process(sm, TRUE); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "SWITCHES CONFIGURED FOR MULTICAST"); } osm_guid_mgr_process(sm); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "ALIAS GUIDS CONFIGURED"); /* * The LINK_PORTS state is required since we cannot count on * the port state change MADs to succeed. This is an artifact * of the spec defining state change from state X to state X * as an error. The hardware then is not required to process * other parameters provided by the Set(PortInfo) Packet. */ osm_link_mgr_process(sm, IB_LINK_NO_CHANGE); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "LINKS PORTS CONFIGURED - SET LINKS TO ARMED STATE"); osm_link_mgr_process(sm, IB_LINK_ARMED); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "LINKS ARMED - SET LINKS TO ACTIVE STATE"); osm_link_mgr_process(sm, IB_LINK_ACTIVE); if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats)) return; /* * The sweep completed! */ /* Now do GSI configuration */ osm_congestion_control_setup(sm->p_subn->p_osm); if (osm_congestion_control_wait_pending_transactions (sm->p_subn->p_osm)) return; /* * Send trap 64 on newly discovered endports */ state_mgr_report_new_ports(sm); /* in any case we zero this flag */ sm->p_subn->coming_out_of_standby = FALSE; /* If there were errors - then the subnet is not really up */ if (sm->p_subn->subnet_initialization_error == TRUE) { osm_log_v2(sm->p_log, OSM_LOG_SYS, FILE_ID, "Errors during initialization\n"); OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_ERROR, "ERRORS DURING INITIALIZATION"); } else { sm->p_subn->need_update = 0; osm_dump_all(sm->p_subn->p_osm); state_mgr_up_msg(sm); sm->p_subn->first_time_master_sweep = FALSE; sm->p_subn->set_client_rereg_on_sweep = FALSE; if (OSM_LOG_IS_ACTIVE_V2(sm->p_log, OSM_LOG_VERBOSE) || sm->p_subn->opt.sa_db_dump) osm_sa_db_file_dump(sm->p_subn->p_osm); } /* * Finally signal the subnet up event */ cl_event_signal(&sm->subnet_up_event); osm_opensm_report_event(sm->p_subn->p_osm, OSM_EVENT_ID_SUBNET_UP, NULL); /* if we got a signal to force heavy sweep or errors * in the middle of the sweep - try another sweep. */ if (sm->p_subn->force_heavy_sweep || sm->p_subn->subnet_initialization_error) osm_sm_signal(sm, OSM_SIGNAL_SWEEP); /* Write a new copy of our persistent guid2mkey database */ osm_db_store(sm->p_subn->p_g2m); osm_db_store(sm->p_subn->p_neighbor); }