void cl_disp_construct(IN cl_dispatcher_t * const p_disp) { CL_ASSERT(p_disp); cl_qlist_init(&p_disp->reg_list); cl_ptr_vector_construct(&p_disp->reg_vec); cl_qlist_init(&p_disp->msg_fifo); cl_spinlock_construct(&p_disp->lock); cl_qpool_construct(&p_disp->msg_pool); }
void osm_vl15_construct(IN osm_vl15_t * p_vl) { memset(p_vl, 0, sizeof(*p_vl)); p_vl->state = OSM_VL15_STATE_INIT; p_vl->thread_state = OSM_THREAD_STATE_NONE; cl_event_construct(&p_vl->signal); cl_spinlock_construct(&p_vl->lock); cl_qlist_init(&p_vl->rfifo); cl_qlist_init(&p_vl->ufifo); cl_thread_construct(&p_vl->poller); }
/********************************************************************** o13-12.1.1: Confirm a valid request for event subscription by responding with an InformInfo attribute that is a copy of the data in the Set(InformInfo) request. **********************************************************************/ static void __osm_infr_rcv_respond(IN osm_sa_t * sa, IN osm_madw_t * const p_madw) { cl_qlist_t rec_list; osm_iir_item_t *item; OSM_LOG_ENTER(sa->p_log); OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Generating successful InformInfo response\n"); item = malloc(sizeof(*item)); if (!item) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4303: " "rec_item alloc failed\n"); goto Exit; } memcpy(&item->rec, ib_sa_mad_get_payload_ptr(osm_madw_get_sa_mad_ptr(p_madw)), sizeof(item->rec)); cl_qlist_init(&rec_list); cl_qlist_insert_tail(&rec_list, &item->list_item); osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
ib_api_status_t osm_vendor_init(IN osm_vendor_t * const p_vend, IN osm_log_t * const p_log, IN const uint32_t timeout) { ib_api_status_t status = IB_SUCCESS; OSM_LOG_ENTER(p_log); p_vend->p_transport_info = NULL; p_vend->p_log = p_log; p_vend->resp_timeout = timeout; p_vend->ttime_timeout = timeout * OSMV_TXN_TIMEOUT_FACTOR; cl_qlist_init(&p_vend->bind_handles); /* update the run_randomizer flag */ if (getenv("OSM_PKT_DROP_RATE") != NULL && atol(getenv("OSM_PKT_DROP_RATE")) != 0) { /* if the OSM_PKT_DROP_RATE global variable is defined to a non-zero value - then the randomizer should be called. Need to create the packet randomizer object */ p_vend->run_randomizer = TRUE; status = osm_pkt_randomizer_init(&(p_vend->p_pkt_randomizer), p_log); if (status != IB_SUCCESS) return status; } else { p_vend->run_randomizer = FALSE; p_vend->p_pkt_randomizer = NULL; } OSM_LOG_EXIT(p_log); return (IB_SUCCESS); }
ib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl) { cl_map_init(&p_pkey_tbl->accum_pkeys, 1); cl_ptr_vector_init(&p_pkey_tbl->blocks, 0, 1); cl_ptr_vector_init(&p_pkey_tbl->new_blocks, 0, 1); cl_map_init(&p_pkey_tbl->keys, 1); cl_qlist_init(&p_pkey_tbl->pending); p_pkey_tbl->last_pkey_idx = 0; p_pkey_tbl->used_blocks = 0; p_pkey_tbl->max_blocks = 0; p_pkey_tbl->rcv_blocks_cnt = 0; p_pkey_tbl->indx0_pkey = 0; return IB_SUCCESS; }
ib_api_status_t osm_vendor_init(IN osm_vendor_t * const p_vend, IN osm_log_t * const p_log, IN const uint32_t timeout) { FSTATUS Status; PUMADT_GET_INTERFACE uMadtGetInterface; char *error; umadt_obj_t *p_umadt_obj = (umadt_obj_t *) p_vend; OSM_LOG_ENTER(p_log); p_umadt_obj->p_log = p_log; p_umadt_obj->timeout = timeout; p_umadt_obj->umadt_handle = dlopen("libibt.so", RTLD_NOW); if (!p_umadt_obj->umadt_handle) { printf("Could not load libibt.so <%s>\n", dlerror()); return IB_ERROR; } uMadtGetInterface = dlsym(p_umadt_obj->umadt_handle, "uMadtGetInterface"); if ((error = dlerror()) != NULL) { printf("Could not resolve symbol uMadtGetInterface ERROR<%s>\n", error); return IB_ERROR; } Status = (*uMadtGetInterface) (&p_umadt_obj->uMadtInterface); if (Status != FSUCCESS) { printf(" Error in getting uMADT interface ERROR<%d>\n", Status); return IB_ERROR; } /* Initialize the register list and register list lock */ cl_qlist_init(&p_umadt_obj->register_list); cl_spinlock_construct(&p_umadt_obj->register_lock); CL_ASSERT(cl_spinlock_init(&p_umadt_obj->register_lock) == CL_SUCCESS); p_umadt_obj->init_done = TRUE; printf("*****SUCCESS*****\n"); OSM_LOG_EXIT(p_log); return IB_SUCCESS; }
cl_status_t cl_event_wheel_init(IN cl_event_wheel_t * const p_event_wheel) { cl_status_t cl_status = CL_SUCCESS; /* initialize */ p_event_wheel->p_external_lock = NULL; p_event_wheel->closing = FALSE; cl_status = cl_spinlock_init(&(p_event_wheel->lock)); if (cl_status != CL_SUCCESS) return cl_status; cl_qlist_init(&p_event_wheel->events_wheel); cl_qmap_init(&p_event_wheel->events_map); /* init the timer with timeout */ cl_status = cl_timer_init(&p_event_wheel->timer, __cl_event_wheel_callback, p_event_wheel); /* cb context */ return cl_status; }
void osm_transaction_mgr_init(IN osm_vendor_t * const p_vend) { cl_status_t cl_status; osm_transaction_mgr_t *trans_mgr_p; OSM_LOG_ENTER(p_vend->p_log); CL_ASSERT(p_vend->p_transaction_mgr == NULL); (osm_transaction_mgr_t *) p_vend->p_transaction_mgr = (osm_transaction_mgr_t *) malloc(sizeof(osm_transaction_mgr_t)); trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; /* construct lock object */ cl_spinlock_construct(&(trans_mgr_p->transaction_mgr_lock)); CL_ASSERT(cl_spinlock_init(&(trans_mgr_p->transaction_mgr_lock)) == CL_SUCCESS); /* initialize the qlist */ trans_mgr_p->madw_reqs_list_p = (cl_qlist_t *) malloc(sizeof(cl_qlist_t)); cl_qlist_init(trans_mgr_p->madw_reqs_list_p); /* initialize the qmap */ trans_mgr_p->madw_by_tid_map_p = (cl_qmap_t *) malloc(sizeof(cl_qmap_t)); cl_qmap_init(trans_mgr_p->madw_by_tid_map_p); /* create the timer used by the madw_req_list */ cl_timer_construct(&(trans_mgr_p->madw_list_timer)); /* init the timer with timeout. */ cl_status = cl_timer_init(&trans_mgr_p->madw_list_timer, __osm_transaction_mgr_callback, p_vend); if (cl_status != CL_SUCCESS) { osm_log(p_vend->p_log, OSM_LOG_ERROR, "osm_transaction_mgr_init : ERROR 1000: " "Failed to initialize madw_reqs_list timer\n"); } OSM_LOG_EXIT(p_vend->p_log); }
static int ucast_mgr_build_lfts(osm_ucast_mgr_t * p_mgr) { cl_qlist_init(&p_mgr->port_order_list); if (p_mgr->p_subn->opt.guid_routing_order_file) { OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Fetching guid routing order file \'%s\'\n", p_mgr->p_subn->opt.guid_routing_order_file); if (parse_node_map(p_mgr->p_subn->opt.guid_routing_order_file, add_guid_to_order_list, p_mgr)) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A0D: " "cannot parse guid routing order file \'%s\'\n", p_mgr->p_subn->opt.guid_routing_order_file); } sort_ports_by_switch_load(p_mgr); if (p_mgr->p_subn->opt.port_prof_ignore_file) { cl_qmap_apply_func(&p_mgr->p_subn->sw_guid_tbl, clear_prof_ignore_flag, NULL); if (parse_node_map(p_mgr->p_subn->opt.port_prof_ignore_file, mark_ignored_port, p_mgr)) { OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A0E: " "cannot parse port prof ignore file \'%s\'\n", p_mgr->p_subn->opt.port_prof_ignore_file); } } cl_qmap_apply_func(&p_mgr->p_subn->port_guid_tbl, add_port_to_order_list, p_mgr); cl_qmap_apply_func(&p_mgr->p_subn->sw_guid_tbl, ucast_mgr_process_tbl, p_mgr); cl_qlist_remove_all(&p_mgr->port_order_list); return 0; }
/* * Creates the process global timer provider. Must be called by the shared * object framework to solve all serialization issues. */ cl_status_t __cl_timer_prov_create(void) { CL_ASSERT(gp_timer_prov == NULL); gp_timer_prov = malloc(sizeof(cl_timer_prov_t)); if (!gp_timer_prov) return (CL_INSUFFICIENT_MEMORY); else memset(gp_timer_prov, 0, sizeof(cl_timer_prov_t)); cl_qlist_init(&gp_timer_prov->queue); pthread_mutex_init(&gp_timer_prov->mutex, NULL); pthread_cond_init(&gp_timer_prov->cond, NULL); if (pthread_create(&gp_timer_prov->thread, NULL, __cl_timer_prov_cb, NULL)) { __cl_timer_prov_destroy(); return (CL_ERROR); } return (CL_SUCCESS); }
osm_bind_handle_t osm_vendor_bind(IN osm_vendor_t * const p_vend, IN osm_bind_info_t * const p_osm_bind_info, IN osm_mad_pool_t * const p_mad_pool, IN osm_vend_mad_recv_callback_t mad_recv_callback, IN void *context) { cl_status_t cl_status; FSTATUS Status; /* GEN1 Status for Umadt */ mad_bind_info_t *p_mad_bind_info; RegisterClassStruct *p_umadt_reg_class; umadt_obj_t *p_umadt_obj; OSM_LOG_ENTER(((umadt_obj_t *) p_vend)->p_log); CL_ASSERT(p_vend); p_umadt_obj = (umadt_obj_t *) p_vend; /* Sanity check */ CL_ASSERT(p_umadt_obj->init_done); CL_ASSERT(p_osm_bind_info); CL_ASSERT(p_mad_pool); CL_ASSERT(mad_recv_callback); /* Allocate memory for registering the handle. */ p_mad_bind_info = (mad_bind_info_t *) malloc(sizeof(*p_mad_bind_info)); if (p_mad_bind_info) { memset(p_mad_bind_info, 0, sizeof(*p_mad_bind_info)); p_umadt_reg_class = &p_mad_bind_info->umadt_reg_class; } p_umadt_reg_class->PortGuid = cl_ntoh64(p_osm_bind_info->port_guid); p_umadt_reg_class->ClassId = p_osm_bind_info->mad_class; p_umadt_reg_class->ClassVersion = p_osm_bind_info->class_version; p_umadt_reg_class->isResponder = p_osm_bind_info->is_responder; p_umadt_reg_class->isTrapProcessor = p_osm_bind_info->is_trap_processor; p_umadt_reg_class->isReportProcessor = p_osm_bind_info->is_report_processor; p_umadt_reg_class->SendQueueSize = p_osm_bind_info->send_q_size; p_umadt_reg_class->RecvQueueSize = p_osm_bind_info->recv_q_size; p_umadt_reg_class->NotifySendCompletion = TRUE; p_mad_bind_info->p_umadt_obj = p_umadt_obj; p_mad_bind_info->p_mad_pool = p_mad_pool; p_mad_bind_info->mad_recv_callback = mad_recv_callback; p_mad_bind_info->client_context = context; /* register with Umadt for MAD interface */ Status = p_umadt_obj->uMadtInterface.uMadtRegister(p_umadt_reg_class, &p_mad_bind_info-> umadt_handle); if (Status != FSUCCESS) { free(p_mad_bind_info); OSM_LOG_EXIT(p_umadt_obj->p_log); return (OSM_BIND_INVALID_HANDLE); } CL_ASSERT(p_mad_bind_info->umadt_handle); /* */ /* Start a worker thread to process receives. */ /* */ cl_thread_construct(&p_mad_bind_info->recv_processor_thread); cl_status = cl_thread_init(&p_mad_bind_info->recv_processor_thread, __mad_recv_processor, (void *)p_mad_bind_info, "mad_recv_worker"); CL_ASSERT(cl_status == CL_SUCCESS); cl_qlist_init(&p_mad_bind_info->trans_ctxt_list); cl_spinlock_construct(&p_mad_bind_info->trans_ctxt_lock); cl_spinlock_init(&p_mad_bind_info->trans_ctxt_lock); cl_spinlock_construct(&p_mad_bind_info->timeout_list_lock); cl_spinlock_init(&p_mad_bind_info->timeout_list_lock); cl_status = cl_timer_init(&p_mad_bind_info->timeout_timer, __osm_vendor_timer_callback, (void *)p_mad_bind_info); CL_ASSERT(cl_status == CL_SUCCESS); cl_qlist_init(&p_mad_bind_info->timeout_list); /* */ /* Insert the mad_reg_struct in list and return pointer to it as the handle */ /* */ cl_spinlock_acquire(&p_umadt_obj->register_lock); cl_qlist_insert_head(&p_umadt_obj->register_list, &p_mad_bind_info->list_item); cl_spinlock_release(&p_umadt_obj->register_lock); /* A timeout value of 0 means disable timeouts. */ if (p_umadt_obj->timeout) { cl_timer_start(&p_mad_bind_info->timeout_timer, DEFAULT_TIMER_INTERVAL_MSEC); } OSM_LOG_EXIT(p_umadt_obj->p_log); return ((osm_bind_handle_t) p_mad_bind_info); }
/********************************************************************** Received a Get(InformInfoRecord) or GetTable(InformInfoRecord) MAD **********************************************************************/ static void osm_infr_rcv_process_get_method(IN osm_sa_t * sa, IN osm_madw_t * const p_madw) { char gid_str[INET6_ADDRSTRLEN]; ib_sa_mad_t *p_rcvd_mad; const ib_inform_info_record_t *p_rcvd_rec; cl_qlist_t rec_list; osm_iir_search_ctxt_t context; osm_physp_t *p_req_physp; osm_iir_item_t *item; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_inform_info_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); /* 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 4309: " "Cannot find requester physical port\n"); goto Exit; } if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG)) osm_dump_inform_info_record(sa->p_log, p_rcvd_rec, OSM_LOG_DEBUG); cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.subscriber_gid = p_rcvd_rec->subscriber_gid; context.subscriber_enum = p_rcvd_rec->subscriber_enum; context.sa = sa; context.p_req_physp = p_req_physp; OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Query Subscriber GID:%s(%02X) Enum:0x%X(%02X)\n", inet_ntop(AF_INET6, p_rcvd_rec->subscriber_gid.raw, gid_str, sizeof gid_str), (p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_SUBSCRIBERGID) != 0, cl_ntoh16(p_rcvd_rec->subscriber_enum), (p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_ENUM) != 0); cl_plock_acquire(sa->p_lock); cl_qlist_apply_func(&sa->p_subn->sa_infr_list, __osm_sa_inform_info_rec_by_comp_mask_cb, &context); cl_plock_release(sa->p_lock); /* clear reserved and pad fields in InformInfoRecord */ for (item = (osm_iir_item_t *) cl_qlist_head(&rec_list); item != (osm_iir_item_t *) cl_qlist_end(&rec_list); item = (osm_iir_item_t *)cl_qlist_next(&item->list_item)) { memset(item->rec.reserved, 0, sizeof(item->rec.reserved)); memset(item->rec.pad, 0, sizeof(item->rec.pad)); } osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
int osm_qos_setup(osm_opensm_t * p_osm) { struct qos_config ca_config, sw0_config, swe_config, rtr_config; struct qos_config *cfg; cl_qmap_t *p_tbl; cl_map_item_t *p_next; osm_port_t *p_port; osm_node_t *p_node; int ret = 0; int vlarb_only; qos_mad_list_t *p_list, *p_list_next; qos_mad_item_t *p_port_mad; cl_qlist_t qos_mad_list; if (!p_osm->subn.opt.qos) return 0; OSM_LOG_ENTER(&p_osm->log); qos_build_config(&ca_config, &p_osm->subn.opt.qos_ca_options, &p_osm->subn.opt.qos_options); qos_build_config(&sw0_config, &p_osm->subn.opt.qos_sw0_options, &p_osm->subn.opt.qos_options); qos_build_config(&swe_config, &p_osm->subn.opt.qos_swe_options, &p_osm->subn.opt.qos_options); qos_build_config(&rtr_config, &p_osm->subn.opt.qos_rtr_options, &p_osm->subn.opt.qos_options); cl_qlist_init(&qos_mad_list); cl_plock_excl_acquire(&p_osm->lock); /* read QoS policy config file */ osm_qos_parse_policy_file(&p_osm->subn); p_tbl = &p_osm->subn.port_guid_tbl; p_next = cl_qmap_head(p_tbl); while (p_next != cl_qmap_end(p_tbl)) { vlarb_only = 0; p_port = (osm_port_t *) p_next; p_next = cl_qmap_next(p_next); p_list = (qos_mad_list_t *) malloc(sizeof(*p_list)); if (!p_list) return -1; memset(p_list, 0, sizeof(*p_list)); cl_qlist_init(&p_list->port_mad_list); p_node = p_port->p_node; if (p_node->sw) { if (qos_extports_setup(&p_osm->sm, p_node, &swe_config, &p_list->port_mad_list)) ret = -1; /* skip base port 0 */ if (!ib_switch_info_is_enhanced_port0 (&p_node->sw->switch_info)) goto Continue; if (ib_switch_info_get_opt_sl2vlmapping(&p_node->sw->switch_info) && p_osm->sm.p_subn->opt.use_optimized_slvl && !memcmp(&swe_config.sl2vl, &sw0_config.sl2vl, sizeof(swe_config.sl2vl))) vlarb_only = 1; cfg = &sw0_config; } else if (osm_node_get_type(p_node) == IB_NODE_TYPE_ROUTER) cfg = &rtr_config; else cfg = &ca_config; if (qos_endport_setup(&p_osm->sm, p_port->p_physp, cfg, vlarb_only, &p_list->port_mad_list)) ret = -1; Continue: /* if MAD list is not empty, add it to the global MAD list */ if (cl_qlist_count(&p_list->port_mad_list)) { cl_qlist_insert_tail(&qos_mad_list, &p_list->list_item); } else { free(p_list); } } while (cl_qlist_count(&qos_mad_list)) { p_list_next = (qos_mad_list_t *) cl_qlist_head(&qos_mad_list); while (p_list_next != (qos_mad_list_t *) cl_qlist_end(&qos_mad_list)) { p_list = p_list_next; p_list_next = (qos_mad_list_t *) cl_qlist_next(&p_list->list_item); /* next MAD to send*/ p_port_mad = (qos_mad_item_t *) cl_qlist_remove_head(&p_list->port_mad_list); osm_send_req_mad(&p_osm->sm, p_port_mad->p_madw); osm_qos_mad_delete(&p_port_mad); /* remove the QoS MAD from global MAD list */ if (cl_qlist_count(&p_list->port_mad_list) == 0) { cl_qlist_remove_item(&qos_mad_list, &p_list->list_item); free(p_list); } } } cl_plock_release(&p_osm->lock); OSM_LOG_EXIT(&p_osm->log); return ret; }
void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *p_rcvd_mad; const ib_pkey_table_record_t *p_rcvd_rec; const osm_port_t *p_port = NULL; const ib_pkey_table_t *p_pkey; cl_qlist_t rec_list; osm_pkey_search_ctxt_t context; ib_api_status_t status = IB_SUCCESS; ib_net64_t comp_mask; osm_physp_t *p_req_physp; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_pkey_table_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); comp_mask = p_rcvd_mad->comp_mask; CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_PKEY_TBL_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_rcvd_mad->method != IB_MAD_METHOD_GET && p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4605: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_rcvd_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* p922 - P_KeyTableRecords shall only be provided in response to trusted requests. Check that the requester is a trusted one. */ if (p_rcvd_mad->sm_key != sa->p_subn->opt.sa_key) { /* This is not a trusted requester! */ OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4608: " "Request from non-trusted requester: " "Given SM_Key:0x%016" PRIx64 "\n", cl_ntoh64(p_rcvd_mad->sm_key)); osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); 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 4604: " "Cannot find requester physical port\n"); goto Exit; } p_pkey = (ib_pkey_table_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.sa = sa; context.block_num = p_rcvd_rec->block_num; context.p_req_physp = p_req_physp; OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Got Query Lid:%u(%02X), Block:0x%02X(%02X), Port:0x%02X(%02X)\n", cl_ntoh16(p_rcvd_rec->lid), (comp_mask & IB_PKEY_COMPMASK_LID) != 0, p_rcvd_rec->port_num, (comp_mask & IB_PKEY_COMPMASK_PORT) != 0, p_rcvd_rec->block_num, (comp_mask & IB_PKEY_COMPMASK_BLOCK) != 0); 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_PKEY_COMPMASK_LID) { status = osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid, &p_port); if (status != IB_SUCCESS || p_port == NULL) { status = IB_NOT_FOUND; OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 460B: " "No port found with LID %u\n", cl_ntoh16(p_rcvd_rec->lid)); } } if (status == IB_SUCCESS) { /* if we got a unique port - no need for a port search */ if (p_port) /* this does the loop on all the port phys ports */ __osm_sa_pkey_by_comp_mask(sa, p_port, &context); else cl_qmap_apply_func(&sa->p_subn->port_guid_tbl, __osm_sa_pkey_by_comp_mask_cb, &context); } cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_pkey_table_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
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); }
void osm_lftr_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *p_rcvd_mad; const ib_lft_record_t *p_rcvd_rec; cl_qlist_t rec_list; osm_lftr_search_ctxt_t context; osm_physp_t *p_req_physp; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_lft_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_LFT_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_rcvd_mad->method != IB_MAD_METHOD_GET && p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4408: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_rcvd_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 4407: " "Cannot find requester physical port\n"); goto Exit; } OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_req_physp))); cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.sa = sa; context.p_req_physp = p_req_physp; cl_plock_acquire(sa->p_lock); /* Go over all switches */ cl_qmap_apply_func(&sa->p_subn->sw_guid_tbl, lftr_rcv_by_comp_mask, &context); cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_lft_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->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; }
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); }
void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *p_rcvd_mad; const ib_slvl_table_record_t *p_rcvd_rec; const osm_port_t *p_port = NULL; cl_qlist_t rec_list; osm_slvl_search_ctxt_t context; ib_api_status_t status = IB_SUCCESS; ib_net64_t comp_mask; osm_physp_t *p_req_physp; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_slvl_table_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); comp_mask = p_rcvd_mad->comp_mask; CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_SLVL_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_rcvd_mad->method != IB_MAD_METHOD_GET && p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2604: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_rcvd_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 2603: " "Cannot find requester physical port\n"); goto Exit; } cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.sa = sa; context.in_port_num = p_rcvd_rec->in_port_num; context.p_req_physp = p_req_physp; cl_plock_acquire(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Got Query Lid:%u(%02X), In-Port:0x%02X(%02X), Out-Port:0x%02X(%02X)\n", cl_ntoh16(p_rcvd_rec->lid), (comp_mask & IB_SLVL_COMPMASK_LID) != 0, p_rcvd_rec->in_port_num, (comp_mask & IB_SLVL_COMPMASK_IN_PORT) != 0, p_rcvd_rec->out_port_num, (comp_mask & IB_SLVL_COMPMASK_OUT_PORT) != 0); /* 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_SLVL_COMPMASK_LID) { status = osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid, &p_port); if ((status != IB_SUCCESS) || (p_port == NULL)) { status = IB_NOT_FOUND; OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2608: " "No port found with LID %u\n", cl_ntoh16(p_rcvd_rec->lid)); } } if (status == IB_SUCCESS) { /* if we have a unique port - no need for a port search */ if (p_port) /* this does the loop on all the port phys ports */ __osm_sa_slvl_by_comp_mask(sa, p_port, &context); else cl_qmap_apply_func(&sa->p_subn->port_guid_tbl, __osm_sa_slvl_by_comp_mask_cb, &context); } cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_slvl_table_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
cl_status_t cl_qcpool_init(IN cl_qcpool_t * const p_pool, IN const size_t min_size, IN const size_t max_size, IN const size_t grow_size, IN const size_t * const component_sizes, IN const uint32_t num_components, IN cl_pfn_qcpool_init_t pfn_initializer OPTIONAL, IN cl_pfn_qcpool_dtor_t pfn_destructor OPTIONAL, IN const void *const context) { cl_status_t status; uint32_t i; CL_ASSERT(p_pool); /* Must have a minimum of 1 component. */ CL_ASSERT(num_components); /* A component size array is required. */ CL_ASSERT(component_sizes); /* * If no initializer is provided, the first component must be large * enough to hold a pool item. */ CL_ASSERT(pfn_initializer || (component_sizes[0] >= sizeof(cl_pool_item_t))); cl_qcpool_construct(p_pool); if (num_components > 1 && !pfn_initializer) return (CL_INVALID_SETTING); if (max_size && max_size < min_size) return (CL_INVALID_SETTING); /* * Allocate the array of component sizes and component pointers all * in one allocation. */ p_pool->component_sizes = (size_t *) malloc((sizeof(size_t) + sizeof(void *)) * num_components); if (!p_pool->component_sizes) return (CL_INSUFFICIENT_MEMORY); else memset(p_pool->component_sizes, 0, (sizeof(size_t) + sizeof(void *)) * num_components); /* Calculate the pointer to the array of pointers, used for callbacks. */ p_pool->p_components = (void **)(p_pool->component_sizes + num_components); /* Copy the user's sizes into our array for future use. */ memcpy(p_pool->component_sizes, component_sizes, sizeof(component_sizes[0]) * num_components); /* Store the number of components per object. */ p_pool->num_components = num_components; /* Round up and store the size of the components. */ for (i = 0; i < num_components; i++) { /* * We roundup each component size so that all components * are aligned on a natural boundary. */ p_pool->component_sizes[i] = ROUNDUP(p_pool->component_sizes[i], sizeof(uintn_t)); } p_pool->max_objects = max_size ? max_size : ~(size_t) 0; p_pool->grow_size = grow_size; /* Store callback function pointers. */ p_pool->pfn_init = pfn_initializer; /* may be NULL */ p_pool->pfn_dtor = pfn_destructor; /* may be NULL */ p_pool->context = context; cl_qlist_init(&p_pool->alloc_list); cl_qlist_init(&p_pool->free_list); /* * We are now initialized. We change the initialized flag before * growing since the grow function asserts that we are initialized. */ p_pool->state = CL_INITIALIZED; /* Allocate the minimum number of objects as requested. */ if (!min_size) return (CL_SUCCESS); status = cl_qcpool_grow(p_pool, min_size); /* Trap for error and cleanup if necessary. */ if (status != CL_SUCCESS) cl_qcpool_destroy(p_pool); return (status); }
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); }
/* rank is a SWITCH for BFS purpose */ static int updn_subn_rank(IN updn_t * p_updn) { osm_switch_t *p_sw; osm_physp_t *p_physp, *p_remote_physp; cl_qlist_t list; cl_map_item_t *item; struct updn_node *u, *remote_u; uint8_t num_ports, port_num; osm_log_t *p_log = &p_updn->p_osm->log; unsigned max_rank = 0; OSM_LOG_ENTER(p_log); cl_qlist_init(&list); /* add all roots to the list */ 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; u = p_sw->priv; if (!u->rank) cl_qlist_insert_tail(&list, &u->list); } /* BFS the list till it's empty */ while (!cl_is_qlist_empty(&list)) { u = (struct updn_node *)cl_qlist_remove_head(&list); /* Go over all remote nodes and rank them (if not already visited) */ p_sw = u->sw; num_ports = p_sw->num_ports; OSM_LOG(p_log, OSM_LOG_DEBUG, "Handling switch GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(p_sw->p_node))); for (port_num = 1; port_num < num_ports; port_num++) { ib_net64_t port_guid; /* Current port fetched in order to get remote side */ p_physp = osm_node_get_physp_ptr(p_sw->p_node, port_num); if (!p_physp) continue; p_remote_physp = p_physp->p_remote_physp; /* make sure that all the following occur on p_remote_physp: 1. The port isn't NULL 2. It is a switch */ if (p_remote_physp && p_remote_physp->p_node->sw) { remote_u = p_remote_physp->p_node->sw->priv; port_guid = p_remote_physp->port_guid; if (remote_u->rank > u->rank + 1) { remote_u->rank = u->rank + 1; max_rank = remote_u->rank; cl_qlist_insert_tail(&list, &remote_u->list); OSM_LOG(p_log, OSM_LOG_DEBUG, "Rank of port GUID 0x%" PRIx64 " = %u\n", cl_ntoh64(port_guid), remote_u->rank); } } } } /* Print Summary of ranking */ OSM_LOG(p_log, OSM_LOG_VERBOSE, "Subnet ranking completed. Max Node Rank = %d\n", max_rank); OSM_LOG_EXIT(p_log); return 0; }