コード例 #1
0
void osmv_txn_abort_rmpp_txns(osm_bind_handle_t h_bind)
{
	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
	cl_map_item_t *p_item;
	cl_map_obj_t *p_obj;
	osmv_txn_ctx_t *p_txn;
	osmv_rmpp_send_ctx_t *p_send_ctx;
	cl_qmap_t *p_map = p_bo->txn_mgr.p_txn_map;

	OSM_LOG_ENTER(p_bo->p_vendor->p_log);

	while (FALSE == cl_is_qmap_empty(p_map)) {

		p_item = cl_qmap_head(p_map);
		p_obj = PARENT_STRUCT(p_item, cl_map_obj_t, item);
		p_txn = (osmv_txn_ctx_t *) cl_qmap_obj(p_obj);
		p_send_ctx = osmv_txn_get_rmpp_send_ctx(p_txn);

		if (NULL != p_send_ctx) {

			p_send_ctx->status = IB_INTERRUPTED;

			/* Wake up the sender thread to let it break out */
			cl_event_signal(&p_send_ctx->event);
		}

		cl_qmap_remove_item(p_map, p_item);
	}

	OSM_LOG_EXIT(p_bo->p_vendor->p_log);
}
コード例 #2
0
void osm_transaction_mgr_destroy(IN osm_vendor_t * const p_vend)
{
	osm_transaction_mgr_t *trans_mgr_p;
	cl_list_item_t *p_list_item;
	cl_map_item_t *p_map_item;
	osm_madw_req_t *osm_madw_req_p;

	OSM_LOG_ENTER(p_vend->p_log);

	trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;

	if (p_vend->p_transaction_mgr != NULL) {
		/* we need to get a lock */
		cl_spinlock_acquire(&trans_mgr_p->transaction_mgr_lock);

		/* go over all the items in the list and remove them */
		p_list_item =
		    cl_qlist_remove_head(trans_mgr_p->madw_reqs_list_p);
		while (p_list_item !=
		       cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) {
			osm_madw_req_p = (osm_madw_req_t *) p_list_item;

			if (osm_madw_req_p->p_madw->p_mad)
				osm_log(p_vend->p_log, OSM_LOG_DEBUG,
					"osm_transaction_mgr_destroy: "
					"Found outstanding MADW:%p  TID:<0x%"
					PRIx64 ">.\n", osm_madw_req_p->p_madw,
					osm_madw_req_p->p_madw->p_mad->
					trans_id);
			else
				osm_log(p_vend->p_log, OSM_LOG_DEBUG,
					"osm_transaction_mgr_destroy: "
					"Found outstanding MADW:%p  TID:UNDEFINED.\n",
					osm_madw_req_p->p_madw);

			/*  each item - remove it from the map */
			p_map_item = &(osm_madw_req_p->map_item);
			cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p,
					    p_map_item);
			/*  free the item */
			free(osm_madw_req_p);
			p_list_item =
			    cl_qlist_remove_head(trans_mgr_p->madw_reqs_list_p);
		}
		/*  free the qlist and qmap */
		free(trans_mgr_p->madw_reqs_list_p);
		free(trans_mgr_p->madw_by_tid_map_p);
		/*  reliease and destroy the lock */
		cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
		cl_spinlock_destroy(&(trans_mgr_p->transaction_mgr_lock));
		/*  destroy the timer */
		cl_timer_trim(&trans_mgr_p->madw_list_timer, 1);
		cl_timer_destroy(&trans_mgr_p->madw_list_timer);
		/*  free the transaction_manager object */
		free(trans_mgr_p);
		trans_mgr_p = NULL;
	}

	OSM_LOG_EXIT(p_vend->p_log);
}
コード例 #3
0
static void cache_cleanup_switches(osm_ucast_mgr_t * p_mgr)
{
	cache_switch_t *p_sw;
	cache_switch_t *p_next_sw;
	unsigned port_num;
	boolean_t found_port;

	if (!p_mgr->cache_valid)
		return;

	p_next_sw = (cache_switch_t *) cl_qmap_head(&p_mgr->cache_sw_tbl);
	while (p_next_sw !=
	       (cache_switch_t *) cl_qmap_end(&p_mgr->cache_sw_tbl)) {
		p_sw = p_next_sw;
		p_next_sw = (cache_switch_t *) cl_qmap_next(&p_sw->map_item);

		found_port = FALSE;
		for (port_num = 1; port_num < p_sw->num_ports; port_num++)
			if (p_sw->ports[port_num].remote_lid_ho)
				found_port = TRUE;

		if (!found_port) {
			cl_qmap_remove_item(&p_mgr->cache_sw_tbl,
					    &p_sw->map_item);
			cache_sw_destroy(p_sw);
		}
	}
}
コード例 #4
0
void cl_event_wheel_unreg(IN cl_event_wheel_t * const p_event_wheel,
			  IN uint64_t key)
{
	cl_event_wheel_reg_info_t *p_event;
	cl_map_item_t *p_map_item;

	CL_DBG("cl_event_wheel_unreg: " "Removing key:0x%" PRIx64 "\n", key);

	cl_spinlock_acquire(&p_event_wheel->lock);
	p_map_item = cl_qmap_get(&p_event_wheel->events_map, key);
	if (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {
		/* we found such an item. */
		p_event =
		    PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,
				  map_item);

		/* remove the item from the qlist */
		cl_qlist_remove_item(&p_event_wheel->events_wheel,
				     &(p_event->list_item));
		/* remove the item from the qmap */
		cl_qmap_remove_item(&p_event_wheel->events_map,
				    &(p_event->map_item));

		CL_DBG("cl_event_wheel_unreg: Removed key:0x%" PRIx64 "\n",
		       key);

		/* free the item */
		free(p_event);
	} else {
		CL_DBG("cl_event_wheel_unreg: did not find key:0x%" PRIx64
		       "\n", key);
	}

	cl_spinlock_release(&p_event_wheel->lock);
}
コード例 #5
0
ib_api_status_t
osm_transaction_mgr_get_madw_for_tid(IN osm_vendor_t * const p_vend,
				     IN ib_mad_t * const p_mad,
				     OUT osm_madw_t ** req_madw_p)
{
	osm_transaction_mgr_t *trans_mgr_p;
	osm_madw_req_t *osm_madw_req_p;
	cl_map_item_t *p_map_item;
	uint64_t key;
	OSM_LOG_ENTER(p_vend->p_log);

	trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;

	*req_madw_p = NULL;

	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
		"osm_transaction_mgr_get_madw_for_tid: "
		"Looking for TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);

	key = (uint64_t) p_mad->trans_id;
	cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock));
	p_map_item = cl_qmap_get(trans_mgr_p->madw_by_tid_map_p, key);
	if (p_map_item != cl_qmap_end(trans_mgr_p->madw_by_tid_map_p)) {
		/*  we found such an item.  */
		/*  get the osm_madw_req_p  */
		osm_madw_req_p =
		    PARENT_STRUCT(p_map_item, osm_madw_req_t, map_item);

		/*  Since the Transaction was looked up and provided for */
		/*  processing we retire it */
		cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
				     &(osm_madw_req_p->list_item));
		/*  remove the item from the qmap */
		cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p,
				    &(osm_madw_req_p->map_item));

		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
			"osm_transaction_mgr_get_madw_for_tid: "
			"Removed TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);

		*req_madw_p = osm_madw_req_p->p_madw;
	}

	cl_spinlock_release(&(trans_mgr_p->transaction_mgr_lock));
	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
		"osm_transaction_mgr_get_madw_for_tid: "
		"Got MADW:%p.\n", *req_madw_p);
	OSM_LOG_EXIT(p_vend->p_log);
	return (IB_SUCCESS);
}
コード例 #6
0
ib_api_status_t
osm_transaction_mgr_erase_madw(IN osm_vendor_t * const p_vend,
			       IN ib_mad_t * p_mad)
{
	osm_transaction_mgr_t *trans_mgr_p;
	osm_madw_req_t *osm_madw_req_p;
	uint64_t key;
	cl_map_item_t *p_map_item;
	OSM_LOG_ENTER(p_vend->p_log);

	trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;

	key = (uint64_t) p_mad->trans_id;
	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
		"osm_transaction_mgr_erase_madw: "
		"Removing TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);

	cl_spinlock_acquire(&trans_mgr_p->transaction_mgr_lock);
	p_map_item = cl_qmap_get(trans_mgr_p->madw_by_tid_map_p, key);
	if (p_map_item != cl_qmap_end(trans_mgr_p->madw_by_tid_map_p)) {
		/*  we found such an item.  */
		/*  get the osm_madw_req_p  */
		osm_madw_req_p =
		    PARENT_STRUCT(p_map_item, osm_madw_req_t, map_item);

		/*  remove the item from the qlist */
		cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p,
				     &(osm_madw_req_p->list_item));
		/*  remove the item from the qmap */
		cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p,
				    &(osm_madw_req_p->map_item));

		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
			"osm_transaction_mgr_erase_madw: "
			"Removed TID:<0x%" PRIx64 ">.\n", p_mad->trans_id);

		/*  free the item */
		free(osm_madw_req_p);
	} else {
		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
			"osm_transaction_mgr_erase_madw: "
			"osm_transaction_mgr_erase_madw:<0x%" PRIx64
			"> NOT FOUND.\n", p_mad->trans_id);
	}
	cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);
	OSM_LOG_EXIT(p_vend->p_log);

	return (IB_SUCCESS);
}
コード例 #7
0
void cl_event_wheel_destroy(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;

	/* we need to get a lock */
	cl_spinlock_acquire(&p_event_wheel->lock);

	cl_event_wheel_dump(p_event_wheel);

	/* go over all the items in the list and remove them */
	p_list_item = cl_qlist_remove_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_destroy: Found outstanding event"
		       " key:<0x%" PRIx64 ">\n", p_event->key);

		/* remove it from the map */
		p_map_item = &(p_event->map_item);
		cl_qmap_remove_item(&p_event_wheel->events_map, p_map_item);
		free(p_event);	/* allocated by cl_event_wheel_reg */
		p_list_item =
		    cl_qlist_remove_head(&p_event_wheel->events_wheel);
	}

	/* destroy the timer */
	cl_timer_destroy(&p_event_wheel->timer);

	/* destroy the lock (this should be done without releasing - we don't want
	   any other run to grab the lock at this point. */
	cl_spinlock_release(&p_event_wheel->lock);
	cl_spinlock_destroy(&(p_event_wheel->lock));
}
コード例 #8
0
ファイル: osm_prtn.c プロジェクト: chu11/opensm-snapshot
ib_api_status_t osm_prtn_make_partitions(osm_log_t * p_log, osm_subn_t * p_subn)
{
	struct stat statbuf;
	const char *file_name;
	boolean_t is_config = TRUE;
	boolean_t is_wrong_config = FALSE;
	ib_api_status_t status = IB_SUCCESS;
	cl_map_item_t *p_next;
	osm_prtn_t *p;

	file_name = p_subn->opt.partition_config_file ?
	    p_subn->opt.partition_config_file : OSM_DEFAULT_PARTITION_CONFIG_FILE;
	if (stat(file_name, &statbuf)) {
		OSM_LOG(p_log, OSM_LOG_VERBOSE, "Partition configuration "
			"%s is not accessible (%s)\n", file_name,
			strerror(errno));
		is_config = FALSE;
	}

retry_default:
	/* clean up current port maps */
	p_next = cl_qmap_head(&p_subn->prtn_pkey_tbl);
	while (p_next != cl_qmap_end(&p_subn->prtn_pkey_tbl)) {
		p = (osm_prtn_t *) p_next;
		p_next = cl_qmap_next(&p->map_item);
		cl_map_remove_all(&p->part_guid_tbl);
		cl_map_remove_all(&p->full_guid_tbl);
	}

	global_pkey_counter = 0;

	status = prtn_make_default(p_log, p_subn, !is_config);
	if (status != IB_SUCCESS)
		goto _err;

	if (is_config && osm_prtn_config_parse_file(p_log, p_subn, file_name)) {
		OSM_LOG(p_log, OSM_LOG_VERBOSE, "Partition configuration "
			"was not fully processed\n");
		is_wrong_config = TRUE;
	}

	/* and now clean up empty partitions */
	p_next = cl_qmap_head(&p_subn->prtn_pkey_tbl);
	while (p_next != cl_qmap_end(&p_subn->prtn_pkey_tbl)) {
		p = (osm_prtn_t *) p_next;
		p_next = cl_qmap_next(&p->map_item);
		if (cl_map_count(&p->part_guid_tbl) == 0 &&
		    cl_map_count(&p->full_guid_tbl) == 0) {
			cl_qmap_remove_item(&p_subn->prtn_pkey_tbl,
					    (cl_map_item_t *) p);
			osm_prtn_delete(p_subn, &p);
		}
	}

	if (is_config && is_wrong_config) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "Partition configuration "
			"in error; retrying with default config\n");
		is_config = FALSE;
		goto retry_default;
	}

_err:
	return status;
}
コード例 #9
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);
}
コード例 #10
0
cl_status_t cl_event_wheel_reg(IN cl_event_wheel_t * const p_event_wheel,
			       IN const uint64_t key,
			       IN const uint64_t aging_time_usec,
			       IN cl_pfn_event_aged_cb_t pfn_callback,
			       IN void *const context)
{
	cl_event_wheel_reg_info_t *p_event;
	uint64_t timeout;
	uint32_t to;
	cl_status_t cl_status = CL_SUCCESS;
	cl_list_item_t *prev_event_list_item;
	cl_map_item_t *p_map_item;

	/* Get the lock on the manager */
	cl_spinlock_acquire(&(p_event_wheel->lock));

	cl_event_wheel_dump(p_event_wheel);

	/* Make sure such a key does not exists */
	p_map_item = cl_qmap_get(&p_event_wheel->events_map, key);
	if (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {
		CL_DBG("cl_event_wheel_reg: Already exists key:0x%"
		       PRIx64 "\n", key);

		/* already there - remove it from the list as it is getting a new time */
		p_event =
		    PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,
				  map_item);

		/* remove the item from the qlist */
		cl_qlist_remove_item(&p_event_wheel->events_wheel,
				     &p_event->list_item);
		/* and the qmap */
		cl_qmap_remove_item(&p_event_wheel->events_map,
				    &p_event->map_item);
	} else {
		/* make a new one */
		p_event = (cl_event_wheel_reg_info_t *)
		    malloc(sizeof(cl_event_wheel_reg_info_t));
		p_event->num_regs = 0;
	}

	p_event->key = key;
	p_event->aging_time = aging_time_usec;
	p_event->pfn_aged_callback = pfn_callback;
	p_event->context = context;
	p_event->num_regs++;

	CL_DBG("cl_event_wheel_reg: Registering event key:0x%" PRIx64
	       " aging in %u [msec]\n", p_event->key,
	       (uint32_t) ((p_event->aging_time - cl_get_time_stamp()) / 1000));

	/* If the list is empty - need to start the timer */
	if (cl_is_qlist_empty(&p_event_wheel->events_wheel)) {
		/* Edward Bortnikov 03/29/2003
		 * ++TBD Consider moving the timer manipulation behind the list manipulation.
		 */

		/* calculate the new timeout */
		timeout =
		    (p_event->aging_time - cl_get_time_stamp() + 500) / 1000;

		/* stop the timer if it is running */

		/* Edward Bortnikov 03/29/2003
		 * Don't call cl_timer_stop() because it spins forever.
		 * cl_timer_start() will invoke cl_timer_stop() by itself.
		 *
		 * The problematic scenario is when __cl_event_wheel_callback()
		 * is in race condition with this code. It sets timer.in_timer_cb
		 * to TRUE and then blocks on p_event_wheel->lock. Following this,
		 * the call to cl_timer_stop() hangs. Following this, the whole system
		 * enters into a deadlock.
		 *
		 * cl_timer_stop(&p_event_wheel->timer);
		 */

		/* The timeout for the cl_timer_start should be given as uint32_t.
		   if there is an overflow - warn about it. */
		to = (uint32_t) timeout;
		if (timeout > (uint32_t) timeout) {
			to = 0xffffffff;	/* max 32 bit timer */
			CL_DBG("cl_event_wheel_reg: timeout requested is "
			       "too large. Using timeout: %u\n", to);
		}

		/* start the timer to the timeout [msec] */
		cl_status = cl_timer_start(&p_event_wheel->timer, to);
		if (cl_status != CL_SUCCESS) {
			CL_DBG("cl_event_wheel_reg : ERR 6203: "
			       "Failed to start timer\n");
			goto Exit;
		}
	}

	/* insert the object to the qlist and the qmap */

	/* BUT WE MUST INSERT IT IN A SORTED MANNER */
	prev_event_list_item =
	    cl_qlist_find_from_tail(&p_event_wheel->events_wheel,
				    __event_will_age_before,
				    &p_event->aging_time);

	cl_qlist_insert_next(&p_event_wheel->events_wheel,
			     prev_event_list_item, &p_event->list_item);

	cl_qmap_insert(&p_event_wheel->events_map, key, &(p_event->map_item));

Exit:
	cl_spinlock_release(&p_event_wheel->lock);

	return cl_status;
}