Exemplo n.º 1
0
void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
{
	umadt_obj_t *p_umadt_obj = (umadt_obj_t *) * pp_vend;
	cl_list_item_t *p_list_item;
	uint32_t count, i;
	mad_bind_info_t *p_mad_bind_info;

	OSM_LOG_ENTER(p_umadt_obj->p_log);

	cl_spinlock_acquire(&p_umadt_obj->register_lock);
	p_mad_bind_info =
	    (mad_bind_info_t *) cl_qlist_head(&p_umadt_obj->register_list);
	count = cl_qlist_count(&p_umadt_obj->register_list);
	cl_spinlock_release(&p_umadt_obj->register_lock);
	for (i = 0; i < count; i++) {
		cl_spinlock_acquire(&p_umadt_obj->register_lock);
		p_list_item = cl_qlist_next(&p_mad_bind_info->list_item);
		cl_spinlock_release(&p_umadt_obj->register_lock);
		/*  Unbind this handle */
		/*  osm_vendor_ubind also removesd the item from the list */
		/*  osm_vendor_unbind takes the list lock so release it here */
		osm_vendor_unbind((osm_bind_handle_t) p_mad_bind_info);
		p_mad_bind_info = (mad_bind_info_t *) p_list_item;
	}
	dlclose(p_umadt_obj->umadt_handle);
	free(p_umadt_obj);
	*pp_vend = NULL;

	OSM_LOG_EXIT(p_umadt_obj->p_log);
}
Exemplo n.º 2
0
void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
{
	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
	osm_log_t *p_log = p_bo->p_vendor->p_log;
	cl_list_obj_t *p_obj = NULL;
	cl_list_item_t *p_item, *p_item_tmp;
	cl_qlist_t *const p_bh_list =
	    (cl_qlist_t * const)&p_bo->p_vendor->bind_handles;

	OSM_LOG_ENTER(p_log);

	/* go over all the items in the list and remove the specific item */
	p_item = cl_qlist_head(p_bh_list);
	while (p_item != cl_qlist_end(p_bh_list)) {
		p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
		if (cl_qlist_obj(p_obj) == h_bind) {
			break;
		}
		p_item_tmp = cl_qlist_next(p_item);
		p_item = p_item_tmp;
	}

	CL_ASSERT(p_item != cl_qlist_end(p_bh_list));

	cl_qlist_remove_item(p_bh_list, p_item);
	if (p_obj)
		free(p_obj);

	if (h_bind != 0) {
		__osm_vendor_internal_unbind(h_bind);
	}

	OSM_LOG_EXIT(p_log);
}
Exemplo n.º 3
0
void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
{
	mad_bind_info_t *p_mad_bind_info;
	umadt_obj_t *p_umadt_obj;
	cl_list_item_t *p_list_item, *p_next_list_item;

	CL_ASSERT(h_bind);
	p_mad_bind_info = (mad_bind_info_t *) h_bind;
	p_umadt_obj = p_mad_bind_info->p_umadt_obj;

	/*  sanity check */
	CL_ASSERT(p_umadt_obj);
	CL_ASSERT(p_umadt_obj->init_done);
	CL_ASSERT(__valid_mad_handle(p_mad_bind_info));

	p_umadt_obj->uMadtInterface.uMadtDestroy(&p_mad_bind_info->
						 umadt_handle);
	cl_timer_destroy(&p_mad_bind_info->timeout_timer);
	cl_thread_destroy(&p_mad_bind_info->recv_processor_thread);

	cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
	p_list_item = cl_qlist_head(&p_mad_bind_info->trans_ctxt_list);
	while (p_list_item != cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
		p_next_list_item = cl_qlist_next(p_list_item);
		cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
				     p_list_item);
		free(p_list_item);
		p_list_item = p_next_list_item;
	}
	cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);

	cl_spinlock_acquire(&p_mad_bind_info->timeout_list_lock);
	p_list_item = cl_qlist_head(&p_mad_bind_info->timeout_list);
	while (p_list_item != cl_qlist_end(&p_mad_bind_info->timeout_list)) {
		p_next_list_item = cl_qlist_next(p_list_item);
		cl_qlist_remove_item(&p_mad_bind_info->timeout_list,
				     p_list_item);
		free(p_list_item);
		p_list_item = p_next_list_item;
	}
	cl_spinlock_release(&p_mad_bind_info->timeout_list_lock);

	free(p_mad_bind_info);
}
Exemplo n.º 4
0
void cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel)
{
	cl_list_item_t *p_list_item;
	cl_event_wheel_reg_info_t __attribute__((__unused__)) *p_event;

	p_list_item = cl_qlist_head(&p_event_wheel->events_wheel);

	while (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {
		p_event =
		    PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,
				  list_item);
		CL_DBG("cl_event_wheel_dump: Found event key:<0x%"
		       PRIx64 ">, num_regs:%d, aging time:%" PRIu64 "\n",
		       p_event->key, p_event->num_regs, p_event->aging_time);
		p_list_item = cl_qlist_next(p_list_item);
	}
}
Exemplo n.º 5
0
static void
__osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
			    IN void *context)
{
	osm_ucast_mgr_t *p_mgr = context;
	osm_switch_t *const p_sw = (osm_switch_t *) p_map_item;
	unsigned i, lids_per_port;

	OSM_LOG_ENTER(p_mgr->p_log);

	CL_ASSERT(p_sw && p_sw->p_node);

	OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
		"Processing switch 0x%" PRIx64 "\n",
		cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)));

	/* Initialize LIDs in buffer to invalid port number. */
	memset(p_sw->new_lft, OSM_NO_PATH, IB_LID_UCAST_END_HO + 1);

	if (p_mgr->p_subn->opt.lmc)
		alloc_ports_priv(p_mgr);

	/*
	   Iterate through every port setting LID routes for each
	   port based on base LID and LMC value.
	 */
	lids_per_port = 1 << p_mgr->p_subn->opt.lmc;
	for (i = 0; i < lids_per_port; i++) {
		cl_qlist_t *list = &p_mgr->port_order_list;
		cl_list_item_t *item;
		for (item = cl_qlist_head(list); item != cl_qlist_end(list);
		     item = cl_qlist_next(item)) {
			osm_port_t *port = cl_item_obj(item, port, list_item);
			__osm_ucast_mgr_process_port(p_mgr, p_sw, port, i);
		}
	}

	osm_ucast_mgr_set_fwd_table(p_mgr, p_sw);

	if (p_mgr->p_subn->opt.lmc)
		free_ports_priv(p_mgr);

	OSM_LOG_EXIT(p_mgr->p_log);
}
Exemplo n.º 6
0
/* Dump out the complete state of the event wheel */
void __cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel)
{
	cl_list_item_t *p_list_item;
	cl_map_item_t *p_map_item;
	cl_event_wheel_reg_info_t *p_event;

	printf("************** Event Wheel Dump ***********************\n");
	printf("Event Wheel List has %u items:\n",
	       cl_qlist_count(&p_event_wheel->events_wheel));

	p_list_item = cl_qlist_head(&p_event_wheel->events_wheel);
	while (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {
		p_event =
		    PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,
				  list_item);
		printf("Event key:0x%" PRIx64 " Context:%s NumRegs:%u\n",
		       p_event->key, (char *)p_event->context,
		       p_event->num_regs);

		/* next */
		p_list_item = cl_qlist_next(p_list_item);
	}

	printf("Event Map has %u items:\n",
	       cl_qmap_count(&p_event_wheel->events_map));

	p_map_item = cl_qmap_head(&p_event_wheel->events_map);
	while (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {
		p_event =
		    PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,
				  map_item);
		printf("Event key:0x%" PRIx64 " Context:%s NumRegs:%u\n",
		       p_event->key, (char *)p_event->context,
		       p_event->num_regs);

		/* next */
		p_map_item = cl_qmap_next(p_map_item);
	}

}
Exemplo n.º 7
0
/*
 * This is the internal work function executed by the timer's thread.
 */
static void *__cl_timer_prov_cb(IN void *const context)
{
	int ret;
	cl_timer_t *p_timer;

	pthread_mutex_lock(&gp_timer_prov->mutex);
	while (!gp_timer_prov->exit) {
		if (cl_is_qlist_empty(&gp_timer_prov->queue)) {
			/* Wait until we exit or a timer is queued. */
			/* cond wait does:
			 * pthread_cond_wait atomically unlocks the mutex (as per
			 * pthread_unlock_mutex) and waits for the condition variable
			 * cond to be signaled. The thread execution is suspended and
			 * does not consume any CPU time until the condition variable is
			 * signaled. The mutex must be locked by the calling thread on
			 * entrance to pthread_cond_wait. Before RETURNING TO THE
			 * CALLING THREAD, PTHREAD_COND_WAIT RE-ACQUIRES MUTEX (as per
			 * pthread_lock_mutex).
			 */
			ret = pthread_cond_wait(&gp_timer_prov->cond,
						&gp_timer_prov->mutex);
		} else {
			/*
			 * The timer elements are on the queue in expiration order.
			 * Get the first in the list to determine how long to wait.
			 */

			p_timer =
			    (cl_timer_t *) cl_qlist_head(&gp_timer_prov->queue);
			ret =
			    pthread_cond_timedwait(&gp_timer_prov->cond,
						   &gp_timer_prov->mutex,
						   &p_timer->timeout);

			/*
			   Sleep again on every event other than timeout and invalid
			   Note: EINVAL means that we got behind. This can occur when
			   we are very busy...
			 */
			if (ret != ETIMEDOUT && ret != EINVAL)
				continue;

			/*
			 * The timer expired.  Check the state in case it was cancelled
			 * after it expired but before we got a chance to invoke the
			 * callback.
			 */
			if (p_timer->timer_state != CL_TIMER_QUEUED)
				continue;

			/*
			 * Mark the timer as running to synchronize with its
			 * cancelation since we can't hold the mutex during the
			 * callback.
			 */
			p_timer->timer_state = CL_TIMER_RUNNING;

			/* Remove the item from the timer queue. */
			cl_qlist_remove_item(&gp_timer_prov->queue,
					     &p_timer->list_item);
			pthread_mutex_unlock(&gp_timer_prov->mutex);
			/* Invoke the callback. */
			p_timer->pfn_callback((void *)p_timer->context);

			/* Acquire the mutex again. */
			pthread_mutex_lock(&gp_timer_prov->mutex);
			/*
			 * Only set the state to idle if the timer has not been accessed
			 * from the callback
			 */
			if (p_timer->timer_state == CL_TIMER_RUNNING)
				p_timer->timer_state = CL_TIMER_IDLE;

			/*
			 * Signal any thread trying to manipulate the timer
			 * that expired.
			 */
			pthread_cond_signal(&p_timer->cond);
		}
	}
	gp_timer_prov->thread = 0;
	pthread_mutex_unlock(&gp_timer_prov->mutex);
	pthread_exit(NULL);
}
Exemplo n.º 8
0
void __osm_vendor_timer_callback(IN void *context)
{
	uint64_t current_time;
	mad_bind_info_t *p_mad_bind_info;
	umadt_obj_t *p_umadt_obj;
	uint32_t timeout;

	cl_list_item_t *p_list_item, *p_next_list_item;

	CL_ASSERT(context);

	p_mad_bind_info = (mad_bind_info_t *) context;
	p_umadt_obj = p_mad_bind_info->p_umadt_obj;
	timeout = p_umadt_obj->timeout * 1000;

	current_time = cl_get_time_stamp();

	cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);

	p_list_item = cl_qlist_head(&p_mad_bind_info->trans_ctxt_list);
	while (p_list_item != cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {

		p_next_list_item = cl_qlist_next(p_list_item);

		/*  DEFAULT_PKT_TIMEOUT is in milli seconds */
		if (current_time - ((trans_context_t *) p_list_item)->sent_time
		    > timeout) {
			/*  Add this transaction to the timeout_list */
			cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
					     p_list_item);
			cl_qlist_insert_tail(&p_mad_bind_info->timeout_list,
					     p_list_item);
		}

		p_list_item = p_next_list_item;
	}

	cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);

	p_list_item = cl_qlist_head(&p_mad_bind_info->timeout_list);
	while (p_list_item != cl_qlist_end(&p_mad_bind_info->timeout_list)) {
		osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
			"__osm_vendor_timer_callback: "
			"Timing out transaction context [0x%p].\n",
			((trans_context_t *) p_list_item)->context);

		(*(p_mad_bind_info->mad_recv_callback)) (NULL,
							 p_mad_bind_info->
							 client_context,
							 ((trans_context_t *)
							  p_list_item)->
							 context);

		p_next_list_item = cl_qlist_next(p_list_item);
		cl_qlist_remove_item(&p_mad_bind_info->timeout_list,
				     p_list_item);
		free(p_list_item);
		p_list_item = p_next_list_item;
	}

	cl_timer_start(&p_mad_bind_info->timeout_timer,
		       DEFAULT_TIMER_INTERVAL_MSEC);

}
Exemplo n.º 9
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);
}
Exemplo n.º 10
0
/* this is the callback function of the timer */
void __osm_transaction_mgr_callback(IN void *context)
{
	osm_transaction_mgr_t *trans_mgr_p;
	osm_vendor_t *p_vend = (osm_vendor_t *) context;
	cl_list_item_t *p_list_item;
	cl_list_item_t *p_list_next_item;
	osm_madw_req_t *osm_madw_req_p;
	uint64_t current_time;	/*  [usec] */
	uint32_t new_timeout;	/*  [msec] */
	cl_status_t cl_status;
	ib_mad_t *p_mad;
#ifdef OSM_VENDOR_INTF_MTL
	osm_mtl_bind_info_t *p_bind;
#else
	osm_ts_bind_info_t *p_bind;
#endif
	cl_list_t tmp_madw_p_list;	/*  this list will include all the madw_p that should be removed. */
	cl_list_t retry_madw_p_list;	/*  this list will include all the madw_p that were retried and need to be removed. */
	osm_madw_t *madw_p;

	OSM_LOG_ENTER(p_vend->p_log);

	trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;

	/*  initialize the tmp_madw_p_list */
	cl_list_construct(&tmp_madw_p_list);
	cl_status = cl_list_init(&tmp_madw_p_list, 50);
	if (cl_status != CL_SUCCESS) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"__osm_transaction_mgr_callback : ERROR 1000: "
			"Failed to create tmp_madw_p_list\n");
	}

	cl_list_construct(&retry_madw_p_list);
	cl_status = cl_list_init(&retry_madw_p_list, 50);
	if (cl_status != CL_SUCCESS) {
		osm_log(p_vend->p_log, OSM_LOG_ERROR,
			"__osm_transaction_mgr_callback : ERROR 1000: "
			"Failed to create retry_madw_p_list\n");
	}

	current_time = cl_get_time_stamp();
	cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock));
	p_list_item = cl_qlist_head(trans_mgr_p->madw_reqs_list_p);
	if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
		/*  the list is empty - nothing to do */
		cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
			"__osm_transaction_mgr_callback : Nothing to do\n");
		goto Exit;
	}

	/*  non empty list: */

	/*  get the osm_madw_req_p  */
	osm_madw_req_p = PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item);

	while (osm_madw_req_p->waking_time <= current_time) {
		/*  this object was supposed to have gotten a response */
		/*  we need to decide if we need to retry or done with it. */
		if (osm_madw_req_p->retry_cnt > 0) {
			/*  add to the list of the retrys : */
			cl_list_insert_tail(&retry_madw_p_list, osm_madw_req_p);

			/*  update wakeup time and retry count */
			osm_madw_req_p->waking_time =
			    p_vend->timeout * 1000 + cl_get_time_stamp();
			osm_madw_req_p->retry_cnt--;

			/*  make sure we will get some timer call if not earlier */
			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
				"__osm_transaction_mgr_callback : Timer restart:%u\n",
				p_vend->timeout);

			cl_status =
			    cl_timer_start(&trans_mgr_p->madw_list_timer,
					   p_vend->timeout);

			/*  go to the next object and check if it also needs to be removed - didn't receive response */
			/*  we need to do it before we move current item to the end of the list */
			p_list_next_item = cl_qlist_next(p_list_item);

			/*  remove from the head */
			cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
					     &(osm_madw_req_p->list_item));

			/*  insert the object to the qlist and the qmap */
			cl_qlist_insert_tail(trans_mgr_p->madw_reqs_list_p,
					     &(osm_madw_req_p->list_item));

		} else {
			/*  go to the next object and check if it also needs to be removed - didn't receive response */
			p_list_next_item = cl_qlist_next(p_list_item);

			/*  remove from the head */
			cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
					     &(osm_madw_req_p->list_item));

			/*  add it to the tmp_madw_p_list to be removed */
			cl_list_insert_tail(&tmp_madw_p_list,
					    osm_madw_req_p->p_madw);
			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
				"__osm_transaction_mgr_callback : Found failed transaction madw: %p\n",
				osm_madw_req_p->p_madw);
		}

		/*  Advance */
		p_list_item = p_list_next_item;
		if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
			/*  the list is empty - nothing to do */
			break;
		}

		/*  get the osm_madw_req_p  */
		osm_madw_req_p =
		    PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item);
	}

	/*  look at the current p_list_item. If it is not the end item - then we need to  */
	/*  re-start the timer */
	if (p_list_item != cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
		/*  get the osm_madw_req_p  */
		osm_madw_req_p =
		    PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item);

		/*  we have the object that still didn't get response - re-start the timer */
		/*  start the timer to the timeout (in miliseconds) */
		new_timeout =
		    (osm_madw_req_p->waking_time - cl_get_time_stamp()) / 1000 +
		    1;
		cl_status =
		    cl_timer_start(&trans_mgr_p->madw_list_timer, new_timeout);
		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
			"__osm_transaction_mgr_callback : Timer restart:%u\n",
			new_timeout);

		if (cl_status != CL_SUCCESS) {
			osm_log(p_vend->p_log, OSM_LOG_ERROR,
				"__osm_transaction_mgr_callback : ERROR 1000: "
				"Failed to start timer\n");
		}
	}
	/* if not empty - retry on retry list: */
	if (!cl_is_list_empty(&retry_madw_p_list)) {

		/*  remove all elements that were retried: */
		osm_madw_req_p =
		    (osm_madw_req_t
		     *) (cl_list_remove_head(&retry_madw_p_list));
		while (osm_madw_req_p != NULL) {

			/*  resend: */
			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
				"__osm_transaction_mgr_callback : "
				"Retry %d of madw %p\n",
				OSM_DEFAULT_RETRY_COUNT -
				osm_madw_req_p->retry_cnt,
				osm_madw_req_p->p_madw);

			/*  actually send it */
#ifdef OSM_VENDOR_INTF_MTL
			osm_mtl_send_mad((osm_mtl_bind_info_t *)
					 osm_madw_req_p->p_bind,
					 osm_madw_req_p->p_madw);
#else
			ib_api_status_t
			    osm_ts_send_mad(osm_ts_bind_info_t * p_bind,
					    osm_madw_t * const p_madw);
			osm_ts_send_mad((osm_ts_bind_info_t *) osm_madw_req_p->
					p_bind, osm_madw_req_p->p_madw);
#endif
			/*  next one */
			osm_madw_req_p =
			    (osm_madw_req_t
			     *) (cl_list_remove_head(&retry_madw_p_list));
		}
	}

	/*  if the tmp_madw_p_list has elements - need to call the send_err_callback */
	madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list));
	while (madw_p != NULL) {
		/*  need to remove it from pool */

		/* obtain the madw_p stored as the wrid in the send call */
		p_mad = osm_madw_get_mad_ptr(madw_p);
		p_bind = madw_p->h_bind;
		/*
		   Return any wrappers to the pool that may have been
		   pre-emptively allocated to handle a receive.
		 */
		if (madw_p->vend_wrap.p_resp_madw) {
#ifdef OSM_VENDOR_INTF_MTL
			osm_mad_pool_put(p_bind->p_osm_pool,
					 madw_p->vend_wrap.p_resp_madw);
#else
			osm_mad_pool_put(p_bind->p_osm_pool,
					 madw_p->vend_wrap.p_resp_madw);
#endif
			madw_p->vend_wrap.p_resp_madw = NULL;
		}

		/* invoke the CB */
		(*(osm_vend_mad_send_err_callback_t)
		 (p_bind->send_err_callback)) (p_bind->client_context, madw_p);
		madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list));
	}

Exit:
	OSM_LOG_EXIT(p_vend->p_log);

}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
static void __cl_event_wheel_callback(IN void *context)
{
	cl_event_wheel_t *p_event_wheel = (cl_event_wheel_t *) context;
	cl_list_item_t *p_list_item, *p_prev_event_list_item;
	cl_list_item_t *p_list_next_item;
	cl_event_wheel_reg_info_t *p_event;
	uint64_t current_time;
	uint64_t next_aging_time;
	uint32_t new_timeout;
	cl_status_t cl_status;

	/* might be during closing ...  */
	if (p_event_wheel->closing)
		return;

	current_time = cl_get_time_stamp();

	if (NULL != p_event_wheel->p_external_lock)

		/* Take care of the order of acquiring locks to avoid the deadlock!
		 * The external lock goes first.
		 */
		cl_spinlock_acquire(p_event_wheel->p_external_lock);

	cl_spinlock_acquire(&p_event_wheel->lock);

	p_list_item = cl_qlist_head(&p_event_wheel->events_wheel);
	if (p_list_item == cl_qlist_end(&p_event_wheel->events_wheel))
		/* the list is empty - nothing to do */
		goto Exit;

	/* we found such an item.  get the p_event */
	p_event =
	    PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t, list_item);

	while (p_event->aging_time <= current_time) {
		/* this object has aged - invoke it's callback */
		if (p_event->pfn_aged_callback)
			next_aging_time =
			    p_event->pfn_aged_callback(p_event->key,
						       p_event->num_regs,
						       p_event->context);
		else
			next_aging_time = 0;

		/* point to the next object in the wheel */
		p_list_next_item = cl_qlist_next(p_list_item);

		/* We need to retire the event if the next aging time passed */
		if (next_aging_time < current_time) {
			/* remove it from the map */
			cl_qmap_remove_item(&p_event_wheel->events_map,
					    &(p_event->map_item));

			/* pop p_event from the wheel */
			cl_qlist_remove_head(&p_event_wheel->events_wheel);

			/* delete the event info object - allocated by cl_event_wheel_reg */
			free(p_event);
		} else {
			/* update the required aging time */
			p_event->aging_time = next_aging_time;
			p_event->num_regs++;

			/* do not remove from the map  - but remove from the list head and
			   place in the correct position */

			/* pop p_event from the wheel */
			cl_qlist_remove_head(&p_event_wheel->events_wheel);

			/* find the event that ages just before */
			p_prev_event_list_item =
			    cl_qlist_find_from_tail(&p_event_wheel->
						    events_wheel,
						    __event_will_age_before,
						    &p_event->aging_time);

			/* insert just after */
			cl_qlist_insert_next(&p_event_wheel->events_wheel,
					     p_prev_event_list_item,
					     &p_event->list_item);

			/* as we have modified the list - restart from first item: */
			p_list_next_item =
			    cl_qlist_head(&p_event_wheel->events_wheel);
		}

		/* advance to next event */
		p_list_item = p_list_next_item;
		if (p_list_item == cl_qlist_end(&p_event_wheel->events_wheel))
			/* the list is empty - nothing to do */
			break;

		/* get the p_event */
		p_event =
		    PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,
				  list_item);
	}

	/* We need to restart the timer only if the list is not empty now */
	if (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {
		/* get the p_event */
		p_event =
		    PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,
				  list_item);

		/* start the timer to the timeout [msec] */
		new_timeout =
		    (uint32_t) ((p_event->aging_time - current_time + 500) / 1000);
		CL_DBG("__cl_event_wheel_callback: Restart timer in: "
		       "%u [msec]\n", new_timeout);
		cl_status = cl_timer_start(&p_event_wheel->timer, new_timeout);
		if (cl_status != CL_SUCCESS) {
			CL_DBG("__cl_event_wheel_callback : ERR 6200: "
			       "Failed to start timer\n");
		}
	}

	/* release the lock */
Exit:
	cl_spinlock_release(&p_event_wheel->lock);
	if (NULL != p_event_wheel->p_external_lock)
		cl_spinlock_release(p_event_wheel->p_external_lock);
}