Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
/**********************************************************************
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);
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #8
0
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;
}
Example #10
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);
}
Example #11
0
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);
}
Example #12
0
/**********************************************************************
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);
}
Example #13
0
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);
}
Example #15
0
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);
}
Example #16
0
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);
}
Example #17
0
/**********************************************************************
 * 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);
}
Example #19
0
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);
}
Example #20
0
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);
}
Example #22
0
/*        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;
}