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);
}
Exemple #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);
}
Exemple #3
0
void osm_vl15_post(IN osm_vl15_t * p_vl, IN osm_madw_t * p_madw)
{
	OSM_LOG_ENTER(p_vl->p_log);

	CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY);

	OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG, "Posting p_madw = %p\n", p_madw);

	/*
	   Determine in which fifo to place the pending madw.
	 */
	cl_spinlock_acquire(&p_vl->lock);
	if (p_madw->resp_expected == TRUE) {
		cl_qlist_insert_tail(&p_vl->rfifo, &p_madw->list_item);
		osm_stats_inc_qp0_outstanding(p_vl->p_stats);
	} else
		cl_qlist_insert_tail(&p_vl->ufifo, &p_madw->list_item);
	cl_spinlock_release(&p_vl->lock);

	OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
		"%u QP0 MADs on wire, %u QP0 MADs outstanding\n",
		p_vl->p_stats->qp0_mads_outstanding_on_wire,
		p_vl->p_stats->qp0_mads_outstanding);

	osm_vl15_poll(p_vl);

	OSM_LOG_EXIT(p_vl->p_log);
}
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);
}
Exemple #5
0
int osm_db_delete(IN osm_db_domain_t * p_domain, IN char *const p_key)
{
	osm_log_t *p_log = p_domain->p_db->p_log;
	osm_db_domain_imp_t *p_domain_imp =
	    (osm_db_domain_imp_t *) p_domain->p_domain_imp;
	char *p_prev_val = NULL;
	int res;

	OSM_LOG_ENTER(p_log);

	cl_spinlock_acquire(&p_domain_imp->lock);
	if (st_delete(p_domain_imp->p_hash,
		      (void *) & p_key, (void *) & p_prev_val)) {
		if (st_lookup(p_domain_imp->p_hash,
			      (st_data_t) p_key, (void *) & p_prev_val)) {
			OSM_LOG(p_log, OSM_LOG_ERROR,
				"key:%s still exists in:%s with value:%s\n",
				p_key, p_domain_imp->file_name, p_prev_val);
			res = 1;
		} else {
			free(p_key);
			free(p_prev_val);
			res = 0;
		}
	} else {
		OSM_LOG(p_log, OSM_LOG_DEBUG,
			"fail to find key:%s. delete failed\n", p_key);
		res = 1;
	}
	cl_spinlock_release(&p_domain_imp->lock);

	OSM_LOG_EXIT(p_log);
	return res;
}
/********************************************************************
   __cl_disp_worker

   Description:
   This function takes messages off the FIFO and calls Processmsg()
   This function executes as passive level.

   Inputs:
   p_disp - Pointer to Dispatcher object

   Outputs:
   None

   Returns:
   None
********************************************************************/
void __cl_disp_worker(IN void *context)
{
	cl_disp_msg_t *p_msg;
	cl_dispatcher_t *p_disp = (cl_dispatcher_t *) context;

	cl_spinlock_acquire(&p_disp->lock);

	/* Process the FIFO until we drain it dry. */
	while (cl_qlist_count(&p_disp->msg_fifo)) {
		/* Pop the message at the head from the FIFO. */
		p_msg =
		    (cl_disp_msg_t *) cl_qlist_remove_head(&p_disp->msg_fifo);

		/* we track the tim ethe last message spent in the queue */
		p_disp->last_msg_queue_time_us =
		    cl_get_time_stamp() - p_msg->in_time;

		/*
		 * Release the spinlock while the message is processed.
		 * The user's callback may reenter the dispatcher
		 * and cause the lock to be reaquired.
		 */
		cl_spinlock_release(&p_disp->lock);
		p_msg->p_dest_reg->pfn_rcv_callback((void *)p_msg->p_dest_reg->
						    context,
						    (void *)p_msg->p_data);

		cl_atomic_dec(&p_msg->p_dest_reg->ref_cnt);

		/* The client has seen the data.  Notify the sender as appropriate. */
		if (p_msg->pfn_xmt_callback) {
			p_msg->pfn_xmt_callback((void *)p_msg->context,
						(void *)p_msg->p_data);
			cl_atomic_dec(&p_msg->p_src_reg->ref_cnt);
		}

		/* Grab the lock for the next iteration through the list. */
		cl_spinlock_acquire(&p_disp->lock);

		/* Return this message to the pool. */
		cl_qpool_put(&p_disp->msg_pool, (cl_pool_item_t *) p_msg);
	}

	cl_spinlock_release(&p_disp->lock);
}
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);
}
void osmv_txn_lock(IN osm_bind_handle_t h_bind)
{
	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;

	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
		"--> Acquiring lock %p on bind handle %p\n", &p_bo->lock, p_bo);

	cl_spinlock_acquire(&p_bo->lock);

	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
		"--> Acquired lock %p on bind handle %p\n", &p_bo->lock, p_bo);
}
Exemple #9
0
int osm_db_clear(IN osm_db_domain_t * p_domain)
{
	osm_db_domain_imp_t *p_domain_imp =
	    (osm_db_domain_imp_t *) p_domain->p_domain_imp;

	cl_spinlock_acquire(&p_domain_imp->lock);
	st_foreach(p_domain_imp->p_hash, __osm_clear_tbl_entry,
		   (st_data_t) NULL);
	cl_spinlock_release(&p_domain_imp->lock);

	return 0;
}
Exemple #10
0
int osm_db_store(IN osm_db_domain_t * p_domain)
{
	osm_log_t *p_log = p_domain->p_db->p_log;
	osm_db_domain_imp_t *p_domain_imp;
	FILE *p_file;
	int status = 0;
	char *p_tmp_file_name;

	OSM_LOG_ENTER(p_log);

	p_domain_imp = (osm_db_domain_imp_t *) p_domain->p_domain_imp;
	p_tmp_file_name =
	    (char *)malloc(sizeof(char) *
			   (strlen(p_domain_imp->file_name) + 8));
	strcpy(p_tmp_file_name, p_domain_imp->file_name);
	strcat(p_tmp_file_name, ".tmp");

	cl_spinlock_acquire(&p_domain_imp->lock);

	/* open up the output file */
	p_file = fopen(p_tmp_file_name, "w");
	if (!p_file) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6107: "
			"Failed to open the db file:%s for writing\n",
			p_domain_imp->file_name);
		status = 1;
		goto Exit;
	}

	st_foreach(p_domain_imp->p_hash, __osm_dump_tbl_entry,
		   (st_data_t) p_file);
	fclose(p_file);

	/* move the domain file */
	status = remove(p_domain_imp->file_name);
	if (status) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6109: "
			"Failed to remove file:%s (err:%u)\n",
			p_domain_imp->file_name, status);
	}

	status = rename(p_tmp_file_name, p_domain_imp->file_name);
	if (status) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6108: "
			"Failed to rename the db file to:%s (err:%u)\n",
			p_domain_imp->file_name, status);
	}
Exit:
	cl_spinlock_release(&p_domain_imp->lock);
	free(p_tmp_file_name);
	OSM_LOG_EXIT(p_log);
	return status;
}
Exemple #11
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);
}
Exemple #12
0
int osm_db_keys(IN osm_db_domain_t * p_domain, OUT cl_list_t * p_key_list)
{
	osm_db_domain_imp_t *p_domain_imp =
	    (osm_db_domain_imp_t *) p_domain->p_domain_imp;

	cl_spinlock_acquire(&p_domain_imp->lock);

	st_foreach(p_domain_imp->p_hash,
		   __osm_get_key_of_tbl_entry, (st_data_t) p_key_list);

	cl_spinlock_release(&p_domain_imp->lock);

	return 0;
}
Exemple #13
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);
}
Exemple #14
0
char *osm_db_lookup(IN osm_db_domain_t * p_domain, IN char *const p_key)
{
	osm_db_domain_imp_t *p_domain_imp =
	    (osm_db_domain_imp_t *) p_domain->p_domain_imp;
	char *p_val = NULL;

	cl_spinlock_acquire(&p_domain_imp->lock);

	if (!st_lookup
	    (p_domain_imp->p_hash, (st_data_t) p_key, (void *) & p_val))
		p_val = NULL;

	cl_spinlock_release(&p_domain_imp->lock);

	return p_val;
}
boolean_t __valid_mad_handle(IN mad_bind_info_t * p_mad_bind_info)
{

	umadt_obj_t *p_umadt_obj;

	p_umadt_obj = p_mad_bind_info->p_umadt_obj;

	cl_spinlock_acquire(&p_umadt_obj->register_lock);
	if (!cl_is_item_in_qlist(&p_umadt_obj->register_list,
				 &p_mad_bind_info->list_item)) {
		cl_spinlock_release(&p_umadt_obj->register_lock);
		return FALSE;
	}
	cl_spinlock_release(&p_umadt_obj->register_lock);
	return TRUE;
}
Exemple #16
0
void osm_vl15_destroy(IN osm_vl15_t * p_vl, IN struct osm_mad_pool *p_pool)
{
	osm_madw_t *p_madw;

	OSM_LOG_ENTER(p_vl->p_log);

	/*
	   Signal our threads that we're leaving.
	 */
	p_vl->thread_state = OSM_THREAD_STATE_EXIT;

	/*
	   Don't trigger unless event has been initialized.
	   Destroy the thread before we tear down the other objects.
	 */
	if (p_vl->state != OSM_VL15_STATE_INIT)
		cl_event_signal(&p_vl->signal);

	cl_thread_destroy(&p_vl->poller);

	/*
	   Return the outstanding messages to the pool
	 */

	cl_spinlock_acquire(&p_vl->lock);

	while (!cl_is_qlist_empty(&p_vl->rfifo)) {
		p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo);
		osm_mad_pool_put(p_pool, p_madw);
	}
	while (!cl_is_qlist_empty(&p_vl->ufifo)) {
		p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo);
		osm_mad_pool_put(p_pool, p_madw);
	}

	cl_spinlock_release(&p_vl->lock);

	cl_event_destroy(&p_vl->signal);
	p_vl->state = OSM_VL15_STATE_INIT;
	cl_spinlock_destroy(&p_vl->lock);

	OSM_LOG_EXIT(p_vl->p_log);
}
Exemple #17
0
void osm_vl15_shutdown(IN osm_vl15_t * p_vl, IN osm_mad_pool_t * p_mad_pool)
{
	osm_madw_t *p_madw;

	OSM_LOG_ENTER(p_vl->p_log);

	/* we only should get here after the VL15 interface was initialized */
	CL_ASSERT(p_vl->state == OSM_VL15_STATE_READY);

	/* grap a lock on the object */
	cl_spinlock_acquire(&p_vl->lock);

	/* go over all outstanding MADs and retire their transactions */

	/* first we handle the list of response MADs */
	p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo);
	while (p_madw != (osm_madw_t *) cl_qlist_end(&p_vl->ufifo)) {
		OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
			"Releasing Response p_madw = %p\n", p_madw);

		osm_mad_pool_put(p_mad_pool, p_madw);

		p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->ufifo);
	}

	/* Request MADs we send out */
	p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo);
	while (p_madw != (osm_madw_t *) cl_qlist_end(&p_vl->rfifo)) {
		OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
			"Releasing Request p_madw = %p\n", p_madw);

		osm_mad_pool_put(p_mad_pool, p_madw);
		osm_stats_dec_qp0_outstanding(p_vl->p_stats);

		p_madw = (osm_madw_t *) cl_qlist_remove_head(&p_vl->rfifo);
	}

	/* free the lock */
	cl_spinlock_release(&p_vl->lock);

	OSM_LOG_EXIT(p_vl->p_log);
}
Exemple #18
0
int
osm_db_update(IN osm_db_domain_t * p_domain,
	      IN char *const p_key, IN char *const p_val)
{
	osm_log_t *p_log = p_domain->p_db->p_log;
	osm_db_domain_imp_t *p_domain_imp =
	    (osm_db_domain_imp_t *) p_domain->p_domain_imp;
	char *p_prev_val = NULL;
	char *p_new_key;
	char *p_new_val;

	cl_spinlock_acquire(&p_domain_imp->lock);

	if (st_lookup(p_domain_imp->p_hash,
		      (st_data_t) p_key, (void *) & p_prev_val)) {
		OSM_LOG(p_log, OSM_LOG_DEBUG,
			"Key:%s previously exists in:%s with value:%s\n",
			p_key, p_domain_imp->file_name, p_prev_val);
		p_new_key = p_key;
	} else {
		/* need to allocate the key */
		p_new_key = malloc(sizeof(char) * (strlen(p_key) + 1));
		strcpy(p_new_key, p_key);
	}

	/* need to arange a new copy of the  value */
	p_new_val = malloc(sizeof(char) * (strlen(p_val) + 1));
	strcpy(p_new_val, p_val);

	st_insert(p_domain_imp->p_hash, (st_data_t) p_new_key,
		  (st_data_t) p_new_val);

	if (p_prev_val)
		free(p_prev_val);

	cl_spinlock_release(&p_domain_imp->lock);

	return 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));
}
uint32_t cl_event_wheel_num_regs(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;
	uint32_t num_regs = 0;

	/* try to find the key in the map */
	CL_DBG("cl_event_wheel_num_regs: Looking for 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)) {
		/* ok so we can simply return it's num_regs */
		p_event =
		    PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,
				  map_item);
		num_regs = p_event->num_regs;
	}

	cl_spinlock_release(&p_event_wheel->lock);
	return (num_regs);
}
Exemple #21
0
ib_api_status_t osm_sm_state_mgr_check_legality(osm_sm_t * sm,
						IN osm_sm_signal_t signal)
{
	ib_api_status_t status = IB_SUCCESS;

	CL_ASSERT(sm);

	OSM_LOG_ENTER(sm->p_log);

	/*
	 * The state lock prevents many race conditions from screwing
	 * up the state transition process.
	 */
	cl_spinlock_acquire(&sm->state_lock);

	OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Received signal %s in state %s\n",
		osm_get_sm_mgr_signal_str(signal),
		osm_get_sm_mgr_state_str(sm->p_subn->sm_state));

	switch (sm->p_subn->sm_state) {
	case IB_SMINFO_STATE_DISCOVERING:
		switch (signal) {
		case OSM_SM_SIGNAL_DISCOVERY_COMPLETED:
		case OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED:
		case OSM_SM_SIGNAL_HANDOVER:
			status = IB_SUCCESS;
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_STANDBY:
		switch (signal) {
		case OSM_SM_SIGNAL_POLLING_TIMEOUT:
		case OSM_SM_SIGNAL_DISCOVER:
		case OSM_SM_SIGNAL_DISABLE:
		case OSM_SM_SIGNAL_HANDOVER:
		case OSM_SM_SIGNAL_ACKNOWLEDGE:
			status = IB_SUCCESS;
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_NOTACTIVE:
		switch (signal) {
		case OSM_SM_SIGNAL_STANDBY:
			status = IB_SUCCESS;
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_MASTER:
		switch (signal) {
		case OSM_SM_SIGNAL_HANDOVER:
		case OSM_SM_SIGNAL_HANDOVER_SENT:
			status = IB_SUCCESS;
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	default:
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3209: "
			"Invalid state %s\n",
			osm_get_sm_mgr_state_str(sm->p_subn->sm_state));
		status = IB_INVALID_PARAMETER;

	}

	cl_spinlock_release(&sm->state_lock);

	OSM_LOG_EXIT(sm->p_log);
	return status;
}
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);

}
Exemple #23
0
int osm_db_restore(IN osm_db_domain_t * p_domain)
{

	osm_log_t *p_log = p_domain->p_db->p_log;
	osm_db_domain_imp_t *p_domain_imp =
	    (osm_db_domain_imp_t *) p_domain->p_domain_imp;
	FILE *p_file;
	int status;
	char sLine[OSM_DB_MAX_LINE_LEN];
	boolean_t before_key;
	char *p_first_word, *p_rest_of_line, *p_last;
	char *p_key = NULL;
	char *p_prev_val, *p_accum_val = NULL;
	char *endptr = NULL;
	unsigned int line_num;

	OSM_LOG_ENTER(p_log);

	/* take the lock on the domain */
	cl_spinlock_acquire(&p_domain_imp->lock);

	/* open the file - read mode */
	p_file = fopen(p_domain_imp->file_name, "r");

	if (!p_file) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6103: "
			"Failed to open the db file:%s\n",
			p_domain_imp->file_name);
		status = 1;
		goto Exit;
	}

	/* parse the file allocating new hash tables as required */
	/*
	   states:
	   before_key (0) -> in_key (1)

	   before_key: if a word on the first byte - it is the key. state=in_key
	   the rest of the line is start of the value.
	   in_key: unless the line is empty - add it (with newlines) to the value.
	   if empty: state=before_key
	 */
	status = 0;
	before_key = TRUE;
	line_num = 0;
	/* if we got to EOF in the middle of a key we add a last newline */
	while ((fgets(sLine, OSM_DB_MAX_LINE_LEN, p_file) != NULL) ||
	       ((before_key == FALSE) && strcpy(sLine, "\n"))
	    ) {
		line_num++;
		if (before_key) {
			if ((sLine[0] != ' ') && (sLine[0] != '\t')
			    && (sLine[0] != '\n')) {
				/* we got a new key */
				before_key = FALSE;

				/* handle the key */
				p_first_word =
				    strtok_r(sLine, " \t\n", &p_last);
				if (!p_first_word) {
					OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6104: "
						"Failed to get key from line:%u : %s (file:%s)\n",
						line_num, sLine,
						p_domain_imp->file_name);
					status = 1;
					goto EndParsing;
				}
				if (strlen(p_first_word) > OSM_DB_MAX_GUID_LEN) {
					OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610A: "
						"Illegal key from line:%u : %s (file:%s)\n",
						line_num, sLine,
						p_domain_imp->file_name);
					status = 1;
					goto EndParsing;
				}

				p_key =
				    (char *)malloc(sizeof(char) *
						   (strlen(p_first_word) + 1));
				strcpy(p_key, p_first_word);

				p_rest_of_line = strtok_r(NULL, "\n", &p_last);
				if (p_rest_of_line != NULL) {
					p_accum_val =
					    (char *)malloc(sizeof(char) *
							   (strlen
							    (p_rest_of_line) +
							    1));
					strcpy(p_accum_val, p_rest_of_line);
				} else {
					p_accum_val = (char *)malloc(2);
					strcpy(p_accum_val, "\0");
				}
			} else if (sLine[0] != '\n') {
				OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6105: "
					"How did we get here? line:%u : %s (file:%s)\n",
					line_num, sLine,
					p_domain_imp->file_name);
				status = 1;
				goto EndParsing;
			}
		} /* before key */
		else {
			/* we already have a key */

			if (sLine[0] == '\n') {
				/* got an end of key */
				before_key = TRUE;

				/* make sure the key was not previously used */
				if (st_lookup(p_domain_imp->p_hash,
					      (st_data_t) p_key,
					      (void *) & p_prev_val)) {
					OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6106: "
						"Key:%s already exists in:%s with value:%s."
						" Removing it\n",
						p_key,
						p_domain_imp->file_name,
						p_prev_val);
				} else {
					p_prev_val = NULL;
				}

				OSM_LOG(p_log, OSM_LOG_DEBUG,
					"Got key:%s value:%s\n", p_key,
					p_accum_val);

				/* check that the key is a number */
				if (!strtouq(p_key, &endptr, 0)
				    && *endptr != '\0') {
					OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610B: "
						"Key:%s is invalid\n", p_key);
				} else {
					/* store our key and value */
					st_insert(p_domain_imp->p_hash,
						  (st_data_t) p_key,
						  (st_data_t) p_accum_val);
				}
			} else {
				/* accumulate into the value */
				p_prev_val = p_accum_val;
				p_accum_val =
				    (char *)malloc(strlen(p_prev_val) +
						   strlen(sLine) + 1);
				strcpy(p_accum_val, p_prev_val);
				free(p_prev_val);
				strcat(p_accum_val, sLine);
			}
		}		/* in key */
	}			/* while lines or last line */

EndParsing:
	fclose(p_file);

Exit:
	cl_spinlock_release(&p_domain_imp->lock);
	OSM_LOG_EXIT(p_log);
	return status;
}
/* //////////////////////////////////////////////////////////////////////// */
ib_api_status_t
osm_vendor_send(IN osm_bind_handle_t h_bind,
		IN osm_vend_wrap_t * const p_vend_wrap,
		IN osm_mad_addr_t * const p_mad_addr,
		IN ib_mad_t * const p_mad,
		IN void *transaction_context, IN boolean_t const resp_expected)
{
	FSTATUS Status;

	MadAddrStruct destAddr = { 0 };

	mad_bind_info_t *p_mad_bind_info;
	trans_context_t *p_trans_context;

	umadt_obj_t *p_umadt_obj = NULL;

	uint32_t mad_count = 0;
	MadtStruct *p_madt_struct = NULL;
	uint32_t i;
	uint32_t num_mads = 0;
	uint32_t seg_num = 0;
	uint8_t *p_frag_data = NULL;
	ib_sa_mad_t_vM3 *p_sa_mad = NULL;

	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));
	CL_ASSERT(p_vend_wrap);
	CL_ASSERT(p_mad_addr);
	CL_ASSERT(p_mad);
	/* CL_ASSERT( (ib_mad_t*)&p_vend_wrap->p_madt_struct->IBMad == p_mad ); */

	/*  */
	/*  based on the class, fill out the address info */
	/*  */
	destAddr.DestLid = p_mad_addr->dest_lid;
	destAddr.PathBits = p_mad_addr->path_bits;
	destAddr.StaticRate = p_mad_addr->static_rate;

	if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID ||
	    p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) {
		CL_ASSERT(p_mad_addr->addr_type.smi.source_lid);
		destAddr.AddrType.Smi.SourceLid =
		    p_mad_addr->addr_type.smi.source_lid;
	} else {
		destAddr.AddrType.Gsi.RemoteQpNumber =
		    p_mad_addr->addr_type.gsi.remote_qp;
		destAddr.AddrType.Gsi.RemoteQkey =
		    p_mad_addr->addr_type.gsi.remote_qkey;
		destAddr.AddrType.Gsi.PKey = OSM_DEFAULT_PKEY;
		destAddr.AddrType.Gsi.ServiceLevel =
		    p_mad_addr->addr_type.gsi.service_level;
		destAddr.AddrType.Gsi.GlobalRoute =
		    p_mad_addr->addr_type.gsi.global_route;
		/* destAddr.AddrType.Gsi.GRHInfo = p_mad_addr->addr_type.gsi.grh_info; */
	}
	p_mad->trans_id = cl_ntoh64(p_mad->trans_id) << 24;

	/*  */
	/*  Create a transaction context for this send and save the TID and client context. */
	/*  */

	if (resp_expected) {
		p_trans_context = malloc(sizeof(trans_context_t));
		CL_ASSERT(p_trans_context);

		memset(p_trans_context, 0, sizeof(trans_context_t));
		p_trans_context->trans_id = p_mad->trans_id;
		p_trans_context->context = transaction_context;
		p_trans_context->sent_time = cl_get_time_stamp();

		cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
		cl_qlist_insert_tail(&p_mad_bind_info->trans_ctxt_list,
				     &p_trans_context->list_item);
		cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
	}

	if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID ||
	    p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) {
		/*  Get one mad from uMadt */
		mad_count = 1;
		Status =
		    p_umadt_obj->uMadtInterface.
		    uMadtGetSendMad(p_mad_bind_info->umadt_handle, &mad_count,
				    &p_madt_struct);

		if (Status != FSUCCESS || p_madt_struct == NULL) {
			return IB_ERROR;
		}

		/*  No Segmentation required */
		memcpy(&p_madt_struct->IBMad, p_mad, MAD_BLOCK_SIZE);

		/*  Post the MAD */

		Status =
		    p_umadt_obj->uMadtInterface.uMadtPostSend(p_mad_bind_info->
							      umadt_handle,
							      p_madt_struct,
							      &destAddr);
		if (Status != FSUCCESS) {
			printf("uMadtPostSendMad: Status  = <%d>\n", Status);
			return IB_ERROR;
		}

		/*  Release send MAD */
		Status =
		    p_umadt_obj->uMadtInterface.
		    uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
					p_madt_struct);
		if (Status != FSUCCESS) {
			printf("uMadtReleaseSendMad: Status  = <%d>\n", Status);
			return IB_ERROR;
		}
	} else {

		/*  */
		/*  Segment the MAD, get the required send mads from uMadt and post the MADs. */
		/*  */
		uint32_t payload_len;

		payload_len =
		    cl_ntoh32(((ib_sa_mad_t_vM3 *) p_mad)->payload_len);
		num_mads = payload_len / IB_SA_DATA_SIZE;
		if (payload_len % IB_SA_DATA_SIZE != 0) {
			num_mads++;	/*  Get one additional mad for the remainder */
		}
		for (i = 0; i < num_mads; i++) {
			/*  Get one mad from uMadt */
			mad_count = 1;
			Status =
			    p_umadt_obj->uMadtInterface.
			    uMadtGetSendMad(p_mad_bind_info->umadt_handle,
					    &mad_count, &p_madt_struct);

			if (Status != FSUCCESS || p_madt_struct == NULL) {
				return IB_ERROR;
			}
			/*  Copy client MAD into uMadt's MAD. */
			if (i == 0) {	/*  First Packet */
				/*  Since this is the first MAD, copy the entire MAD_SIZE */
				memcpy(&p_madt_struct->IBMad, p_mad,
				       MAD_BLOCK_SIZE);

				p_frag_data =
				    (uint8_t *) p_mad + MAD_BLOCK_SIZE;

				p_sa_mad =
				    (ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
				if (num_mads == 1) {	/*  Only one Packet */
					p_sa_mad->seg_num = 0;
					p_sa_mad->frag_flag = 5;	/*  Set bit 0 for first pkt and b4 for last pkt */
					/*  the payload length gets copied with the mad header above */
				} else {	/*  More than one packet in this response */

					seg_num = 1;
					p_sa_mad->seg_num =
					    cl_ntoh32(seg_num++);
					p_sa_mad->frag_flag = 1;	/*  Set bit 0 for first pkt */
					/*  the payload length gets copied with the mad header above */
				}

			} else if (i < num_mads - 1) {	/*  Not last packet */
				/*  First copy only the header */
				memcpy(&p_madt_struct->IBMad, p_mad,
				       IB_SA_MAD_HDR_SIZE);
				/*  Set the relevant fields in the SA_MAD_HEADER */
				p_sa_mad =
				    (ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
				p_sa_mad->payload_len =
				    cl_ntoh32(IB_SA_DATA_SIZE);
				p_sa_mad->seg_num = cl_ntoh32(seg_num++);
				p_sa_mad->frag_flag = 0;
				/*  Now copy the fragmented data */
				memcpy(((uint8_t *) & p_madt_struct->IBMad) +
				       IB_SA_MAD_HDR_SIZE, p_frag_data,
				       IB_SA_DATA_SIZE);
				p_frag_data = p_frag_data + IB_SA_DATA_SIZE;

			} else if (i == num_mads - 1) {	/*  Last packet */
				/*  First copy only the header */
				memcpy(&p_madt_struct->IBMad, p_mad,
				       IB_SA_MAD_HDR_SIZE);
				/*  Set the relevant fields in the SA_MAD_HEADER */
				p_sa_mad =
				    (ib_sa_mad_t_vM3 *) & p_madt_struct->IBMad;
				p_sa_mad->seg_num = cl_ntoh32(seg_num++);
				p_sa_mad->frag_flag = 4;	/*  Set Bit 2 for last pkt */
				p_sa_mad->payload_len =
				    cl_ntoh32(cl_ntoh32
					      (((ib_sa_mad_t_vM3 *) p_mad)->
					       payload_len) % IB_SA_DATA_SIZE);
				/*  Now copy the fragmented data */
				memcpy((((uint8_t *) & p_madt_struct->IBMad)) +
				       IB_SA_MAD_HDR_SIZE, p_frag_data,
				       cl_ntoh32(p_sa_mad->payload_len));
				p_frag_data = p_frag_data + IB_SA_DATA_SIZE;

			}
			/*  Post the MAD */
			Status =
			    p_umadt_obj->uMadtInterface.
			    uMadtPostSend(p_mad_bind_info->umadt_handle,
					  p_madt_struct, &destAddr);
			if (Status != FSUCCESS) {
				printf("uMadtPostSendMad: Status  = <%d>\n",
				       Status);
				return IB_ERROR;
			}

			/*  Release send MAD */
			Status =
			    p_umadt_obj->uMadtInterface.
			    uMadtReleaseSendMad(p_mad_bind_info->umadt_handle,
						p_madt_struct);
			if (Status != FSUCCESS) {
				printf("uMadtReleaseSendMad: Status  = <%d>\n",
				       Status);
				return IB_ERROR;
			}
		}
	}
	return (IB_SUCCESS);
}
Exemple #25
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);

}
Exemple #26
0
ib_api_status_t
osm_transaction_mgr_insert_madw(IN osm_bind_handle_t * const p_bind,
				IN osm_madw_t * p_madw)
{
#ifdef OSM_VENDOR_INTF_MTL
	osm_vendor_t *const p_vend = ((osm_mtl_bind_info_t *) p_bind)->p_vend;
#else
	osm_vendor_t *const p_vend = ((osm_ts_bind_info_t *) p_bind)->p_vend;
#endif
	osm_transaction_mgr_t *trans_mgr_p;
	osm_madw_req_t *osm_madw_req_p;
	uint64_t timeout;
	uint64_t waking_time;
	cl_status_t cl_status;
	uint64_t key;
	const ib_mad_t *mad_p = p_madw->p_mad;

	OSM_LOG_ENTER(p_vend->p_log);

	CL_ASSERT(mad_p);

	trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr;

	timeout = (uint64_t) (p_vend->timeout) * 1000;	/* change the miliseconds value of timeout to microseconds. */
	waking_time = timeout + cl_get_time_stamp();

	osm_madw_req_p = (osm_madw_req_t *) malloc(sizeof(osm_madw_req_t));

	osm_madw_req_p->p_madw = p_madw;
	osm_madw_req_p->waking_time = waking_time;
	osm_madw_req_p->retry_cnt = OSM_DEFAULT_RETRY_COUNT;
	osm_madw_req_p->p_bind = p_bind;

	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
		"osm_transaction_mgr_insert_madw: "
		"Inserting MADW:%p with waking_time: <0x%" PRIx64 ">  TID:<0x%"
		PRIx64 ">.\n", p_madw, waking_time, p_madw->p_mad->trans_id);

	/* Get the lock on the manager */
	cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock));
	/* If the list is empty - need to start the timer with timer of timeout (in miliseconds) */
	if (cl_is_qlist_empty(trans_mgr_p->madw_reqs_list_p)) {
		/*  stop the timer if it is running */
		cl_timer_stop(&trans_mgr_p->madw_list_timer);

		/*  start the timer to the timeout (in miliseconds) */
		cl_status = cl_timer_start(&trans_mgr_p->madw_list_timer,
					   p_vend->timeout);
		if (cl_status != CL_SUCCESS) {
			osm_log(p_vend->p_log, OSM_LOG_ERROR,
				"osm_transaction_mgr_insert_madw : ERROR 1000: "
				"Failed to start timer\n");
		}
	}

	/*  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));
	/*  get the key */
	key = (uint64_t) mad_p->trans_id;
	cl_qmap_insert(trans_mgr_p->madw_by_tid_map_p, key,
		       &(osm_madw_req_p->map_item));
	cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock);

	OSM_LOG_EXIT(p_vend->p_log);

	return (IB_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);
}
Exemple #28
0
static void vl15_poller(IN void *p_ptr)
{
	ib_api_status_t status;
	osm_madw_t *p_madw;
	osm_vl15_t *p_vl = p_ptr;
	cl_qlist_t *p_fifo;
	int32_t max_smps = p_vl->max_wire_smps;
	int32_t max_smps2 = p_vl->max_wire_smps2;

	OSM_LOG_ENTER(p_vl->p_log);

	if (p_vl->thread_state == OSM_THREAD_STATE_NONE)
		p_vl->thread_state = OSM_THREAD_STATE_RUN;

	while (p_vl->thread_state == OSM_THREAD_STATE_RUN) {
		/*
		   Start servicing the FIFOs by pulling off MAD wrappers
		   and passing them to the transport interface.
		   There are lots of corner cases here so tread carefully.

		   The unicast FIFO has priority, since somebody is waiting
		   for a timely response.
		 */
		cl_spinlock_acquire(&p_vl->lock);

		if (cl_qlist_count(&p_vl->ufifo) != 0)
			p_fifo = &p_vl->ufifo;
		else
			p_fifo = &p_vl->rfifo;

		p_madw = (osm_madw_t *) cl_qlist_remove_head(p_fifo);

		cl_spinlock_release(&p_vl->lock);

		if (p_madw != (osm_madw_t *) cl_qlist_end(p_fifo)) {
			OSM_LOG(p_vl->p_log, OSM_LOG_DEBUG,
				"Servicing p_madw = %p\n", p_madw);
			if (osm_log_is_active(p_vl->p_log, OSM_LOG_FRAMES))
				osm_dump_dr_smp(p_vl->p_log,
						osm_madw_get_smp_ptr(p_madw),
						OSM_LOG_FRAMES);

			vl15_send_mad(p_vl, p_madw);
		} else
			/*
			   The VL15 FIFO is empty, so we have nothing left to do.
			 */
			status = cl_event_wait_on(&p_vl->signal,
						  EVENT_NO_TIMEOUT, TRUE);

		while (p_vl->p_stats->qp0_mads_outstanding_on_wire >= max_smps &&
		       p_vl->thread_state == OSM_THREAD_STATE_RUN) {
			status = cl_event_wait_on(&p_vl->signal,
						  p_vl->max_smps_timeout,
						  TRUE);
			if (status == CL_TIMEOUT) {
				if (max_smps < max_smps2)
					max_smps++;
				break;
			} else if (status != CL_SUCCESS) {
				OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E02: "
					"Event wait failed (%s)\n",
					CL_STATUS_MSG(status));
				break;
			}
			max_smps = p_vl->max_wire_smps;
		}
	}

	/*
	   since we abort immediately when the state != OSM_THREAD_STATE_RUN
	   we might have some mads on the queues. After the thread exits
	   the vl15 destroy routine should put these mads back...
	 */

	OSM_LOG_EXIT(p_vl->p_log);
}
void __mad_recv_processor(IN void *context)
{
	mad_bind_info_t *p_mad_bind_info = (mad_bind_info_t *) context;
	umadt_obj_t *p_umadt_obj;
	osm_madw_t *p_osm_madw = NULL;
	osm_vend_wrap_t *p_vend_wrap = NULL;
	osm_mad_addr_t osm_mad_addr = { 0 };
	cl_list_item_t *p_list_item;
	void *transaction_context;

	FSTATUS Status;
	MadtStruct *pRecvMad = NULL;
	MadWorkCompletion *pRecvCmp = NULL;

	CL_ASSERT(context);

	p_mad_bind_info = (mad_bind_info_t *) context;
	p_umadt_obj = p_mad_bind_info->p_umadt_obj;
	/*  PollFor a completion */
	/*  if FNOTFOND, then wait for a completion then again poll and return the MAD */
	while (1) {
		Status =
		    p_umadt_obj->uMadtInterface.
		    uMadtPollForRecvCompletion(p_mad_bind_info->umadt_handle,
					       &pRecvMad, &pRecvCmp);
		if (Status != FSUCCESS) {
			if (Status == FNOT_FOUND) {
				/* Wait for a completion */
				Status = p_umadt_obj->uMadtInterface.uMadtWaitForAnyCompletion(p_mad_bind_info->umadt_handle, RECV_COMPLETION, 0x5000);	/* 5 sec timeout */

				if (Status == FTIMEOUT) {
					continue;
				}
				CL_ASSERT(Status == FSUCCESS);

				Status =
				    p_umadt_obj->uMadtInterface.
				    uMadtPollForRecvCompletion(p_mad_bind_info->
							       umadt_handle,
							       &pRecvMad,
							       &pRecvCmp);
				if (Status != FSUCCESS) {
					printf
					    (" mad_recv_worker: Error in PollForRecv returning <%x>\n",
					     Status);
					CL_ASSERT(0);
				}
			} else {
				printf
				    ("uMadtPollForRecvCompletion Status=<%x>\n",
				     Status);
				CL_ASSERT(0);
			}
		}
		CL_ASSERT(pRecvMad);
		CL_ASSERT(pRecvCmp);

		if (((ib_sa_mad_t_vM3 *) (&pRecvMad->IBMad))->frag_flag & 0x20) {
			/*  Ignore the ACK packet */
			Status =
			    p_umadt_obj->uMadtInterface.
			    uMadtReleaseRecvMad(p_mad_bind_info->umadt_handle,
						pRecvMad);
			continue;
		}
		/*  */
		/*  Extract the return address to pass it on to the client */
		/*  */
		osm_mad_addr.dest_lid = pRecvCmp->AddressInfo.DestLid;
		osm_mad_addr.path_bits = pRecvCmp->AddressInfo.PathBits;
		osm_mad_addr.static_rate = pRecvCmp->AddressInfo.StaticRate;

		if (p_mad_bind_info->umadt_reg_class.ClassId ==
		    IB_MCLASS_SUBN_LID
		    || p_mad_bind_info->umadt_reg_class.ClassId ==
		    IB_MCLASS_SUBN_DIR) {
			osm_mad_addr.addr_type.smi.source_lid =
			    pRecvCmp->AddressInfo.AddrType.Smi.SourceLid;
			/* osm_mad_addr.addr_type.smi.port_num = pRecvCmp->AddressInfo.AddrType.Smi.PortNumber; */
		} else {
			osm_mad_addr.addr_type.gsi.remote_qp =
			    pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQpNumber;
			osm_mad_addr.addr_type.gsi.remote_qkey =
			    pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQkey;
			osm_mad_addr.addr_type.gsi.pkey_ix = 0;
			osm_mad_addr.addr_type.gsi.service_level =
			    pRecvCmp->AddressInfo.AddrType.Gsi.ServiceLevel;
			osm_mad_addr.addr_type.gsi.global_route =
			    pRecvCmp->AddressInfo.AddrType.Gsi.GlobalRoute;
			/* osm_mad_addr.addr_type.gsi.grh_info = pRecvCmp->AddressInfo.AddrType.Gsi.GRHInfo; */
		}
		p_osm_madw =
		    osm_mad_pool_get_wrapper(p_mad_bind_info->p_mad_pool,
					     p_mad_bind_info, MAD_BLOCK_SIZE,
					     (ib_mad_t *) & pRecvMad->IBMad,
					     &osm_mad_addr);
		CL_ASSERT(p_osm_madw);
		p_vend_wrap = osm_madw_get_vend_ptr(p_osm_madw);
		CL_ASSERT(p_vend_wrap);
		p_vend_wrap->p_madt_struct = pRecvMad;
		p_vend_wrap->direction = RECEIVE;

		osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
			"__mad_recv_processor: "
			"Received data p_osm_madw[0x%p].\n", p_osm_madw);

		/*  */
		/*  Do TID Processing. */
		/*  */
		/*  If R bit is set swap the TID */

		cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock);
		p_list_item =
		    cl_qlist_find_from_head(&p_mad_bind_info->trans_ctxt_list,
					    __match_tid_context,
					    &p_osm_madw->p_mad->trans_id);

		if (p_list_item ==
		    cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) {
			transaction_context = NULL;
		} else {
			transaction_context =
			    ((trans_context_t *) p_list_item)->context;
			cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list,
					     p_list_item);
			free(p_list_item);
		}
		cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock);
		((ib_mad_t *) p_osm_madw->p_mad)->trans_id =
		    cl_ntoh64(p_osm_madw->p_mad->trans_id >> 24);
		osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG,
			"__mad_recv_processor: "
			"Received data p_osm_madw [0x%p]" "\n\t\t\t\tTID[0x%"
			PRIx64 ", context[%p]. \n", p_osm_madw,
			((ib_mad_t *) p_osm_madw->p_mad)->trans_id,
			transaction_context);

		(*(p_mad_bind_info->mad_recv_callback)) (p_osm_madw,
							 p_mad_bind_info->
							 client_context,
							 transaction_context);

	}
}
Exemple #30
0
ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
					 IN osm_sm_signal_t signal)
{
	ib_api_status_t status = IB_SUCCESS;

	CL_ASSERT(sm);

	OSM_LOG_ENTER(sm->p_log);

	/*
	 * The state lock prevents many race conditions from screwing
	 * up the state transition process.
	 */
	cl_spinlock_acquire(&sm->state_lock);

	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
		"Received signal %s in state %s\n",
		osm_get_sm_mgr_signal_str(signal),
		osm_get_sm_mgr_state_str(sm->p_subn->sm_state));

	switch (sm->p_subn->sm_state) {
	case IB_SMINFO_STATE_DISCOVERING:
		switch (signal) {
		case OSM_SM_SIGNAL_DISCOVERY_COMPLETED:
			/*
			 * Update the state of the SM to MASTER
			 */
			/* Turn on the first_time_master_sweep flag */
			sm->p_subn->first_time_master_sweep = TRUE;
			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
			osm_report_sm_state(sm);
			/*
			 * Make sure to set the subnet master_sm_base_lid
			 * to the sm_base_lid value
			 */
			sm->p_subn->master_sm_base_lid =
			    sm->p_subn->sm_base_lid;
			break;
		case OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED:
			/*
			 * Finished all discovery actions - move to STANDBY
			 * start the polling
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_STANDBY;
			osm_report_sm_state(sm);
			/*
			 * Since another SM is doing the LFT config - we should not
			 * ignore the results of it
			 */
			sm->p_subn->ignore_existing_lfts = FALSE;

			sm_state_mgr_start_polling(sm);
			break;
		case OSM_SM_SIGNAL_HANDOVER:
			/*
			 * Do nothing. We will discover it later on. If we already discovered
			 * this SM, and got the HANDOVER - this means the remote SM is of
			 * lower priority. In this case we will stop polling it (since it is
			 * a lower priority SM in STANDBY state).
			 */
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_STANDBY:
		switch (signal) {
		case OSM_SM_SIGNAL_POLLING_TIMEOUT:
		case OSM_SM_SIGNAL_DISCOVER:
			/*
			 * case 1: Polling timeout occured - this means that the Master SM
			 * is no longer alive.
			 * case 2: Got a signal to move to DISCOVERING
			 * Move to DISCOVERING state and start sweeping
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_DISCOVERING;
			osm_report_sm_state(sm);
			sm->p_subn->coming_out_of_standby = TRUE;
			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
			break;
		case OSM_SM_SIGNAL_DISABLE:
			/*
			 * Update the state to NOT_ACTIVE
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_NOTACTIVE;
			osm_report_sm_state(sm);
			osm_vendor_set_sm(sm->mad_ctrl.h_bind, FALSE);
			break;
		case OSM_SM_SIGNAL_HANDOVER:
			/*
			 * Update the state to MASTER, and start sweeping
			 * OPTIONAL: send ACKNOWLEDGE
			 */
			/* Turn on the first_time_master_sweep flag */
			sm->p_subn->first_time_master_sweep = TRUE;
			/*
			 * Turn on the force_heavy_sweep - we want a
			 * heavy sweep to occur on the first sweep of this SM.
			 */
			sm->p_subn->force_heavy_sweep = TRUE;

			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
			osm_report_sm_state(sm);
			/*
			 * Make sure to set the subnet master_sm_base_lid
			 * to the sm_base_lid value
			 */
			sm->p_subn->master_sm_base_lid =
			    sm->p_subn->sm_base_lid;
			sm->p_subn->coming_out_of_standby = TRUE;
			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
			break;
		case OSM_SM_SIGNAL_ACKNOWLEDGE:
			/*
			 * Do nothing - already moved to STANDBY
			 */
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_NOTACTIVE:
		switch (signal) {
		case OSM_SM_SIGNAL_STANDBY:
			/*
			 * Update the state to STANDBY
			 * start the polling
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_STANDBY;
			osm_report_sm_state(sm);
			sm_state_mgr_start_polling(sm);
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	case IB_SMINFO_STATE_MASTER:
		switch (signal) {
		case OSM_SM_SIGNAL_POLLING_TIMEOUT:
			/*
			 * We received a polling timeout - this means that we
			 * waited for a remote master sm to send us a handover,
			 * but didn't get it, and didn't get a response from
			 * that remote sm.
			 * We want to force a heavy sweep - hopefully this
			 * occurred because the remote sm died, and we'll find
			 * this out and configure the subnet after a heavy sweep.
			 * We also want to clear the p_polling_sm object - since
			 * we are done polling on that remote sm - we are
			 * sweeping again.
			 */
		case OSM_SM_SIGNAL_HANDOVER:
			/*
			 * If we received a handover in a master state - then we
			 * want to force a heavy sweep. This means that either
			 * we are in a sweep currently - in this case - no
			 * change, or we are in idle state - since we
			 * recognized a master SM before - so we want to make a
			 * heavy sweep and reconfigure the new subnet.
			 * We also want to clear the p_polling_sm object - since
			 * we are done polling on that remote sm - we got a
			 * handover from it.
			 */
			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
				"Forcing heavy sweep. "
				"Received OSM_SM_SIGNAL_HANDOVER or OSM_SM_SIGNAL_POLLING_TIMEOUT\n");
			sm->p_polling_sm = NULL;
			sm->p_subn->force_heavy_sweep = TRUE;
			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
			break;
		case OSM_SM_SIGNAL_HANDOVER_SENT:
			/*
			 * Just sent a HANDOVER signal - move to STANDBY
			 * start the polling
			 */
			sm->p_subn->sm_state = IB_SMINFO_STATE_STANDBY;
			osm_report_sm_state(sm);
			sm_state_mgr_start_polling(sm);
			break;
		case OSM_SM_SIGNAL_WAIT_FOR_HANDOVER:
			/*
			 * We found a remote master SM, and we are waiting for
			 * it to handover the mastership to us. Need to start
			 * polling that SM, to make sure it is alive, if it
			 * isn't - then we should move back to discovering,
			 * since something must have happened to it.
			 */
			sm_state_mgr_start_polling(sm);
			break;
		case OSM_SM_SIGNAL_DISCOVER:
			sm->p_subn->sm_state = IB_SMINFO_STATE_DISCOVERING;
			osm_report_sm_state(sm);
			break;
		default:
			sm_state_mgr_signal_error(sm, signal);
			status = IB_INVALID_PARAMETER;
			break;
		}
		break;

	default:
		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3208: "
			"Invalid state %s\n",
			osm_get_sm_mgr_state_str(sm->p_subn->sm_state));

	}

	cl_spinlock_release(&sm->state_lock);

	OSM_LOG_EXIT(sm->p_log);
	return status;
}