Example #1
0
/*
  Since a race can accure on requests. Meaning - a response is received before
  the send_callback is called - we will save both the madw_p and the fact
  whether or not it is a response. A race can occure only on requests that did
  not fail, and then the madw_p will be put back in the pool before the
  callback.
*/
uint64_t __osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)
{
	uint64_t wrid = 0;

	CL_ASSERT(p_madw->p_mad);

	memcpy(&wrid, &p_madw, sizeof(osm_madw_t *));
	wrid = (wrid << 1) |
	    ib_mad_is_response(p_madw->p_mad) |
	    (p_madw->p_mad->method == IB_MAD_METHOD_TRAP_REPRESS);
	return wrid;
}
static osmv_disp_route_t
__osmv_dispatch_route(IN osm_bind_handle_t h_bind,
		      IN const ib_mad_t * p_mad, OUT osmv_txn_ctx_t ** pp_txn)
{
	ib_api_status_t ret;
	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
	boolean_t is_resp = ib_mad_is_response(p_mad);
	boolean_t is_txn;
	uint64_t key = cl_ntoh64(p_mad->trans_id);

	CL_ASSERT(NULL != pp_txn);

	ret = osmv_txn_lookup(h_bind, key, pp_txn);
	is_txn = (IB_SUCCESS == ret);

	if (FALSE == is_txn && TRUE == is_resp) {
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
			"Received a response to a non-started/aged-out transaction (tid=0x%" PRIx64 "). "
			"Dropping the MAD.\n", key);
		return OSMV_ROUTE_DROP;
	}

	if (TRUE == osmv_mad_is_rmpp(p_mad)) {
		/* An RMPP transaction. The filtering is more delicate there */
		return OSMV_ROUTE_RMPP;
	}

	if (TRUE == is_txn && FALSE == is_resp) {
		/* Does this MAD try to start a transaction with duplicate tid? */
		osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
			"Duplicate TID 0x%" PRIx64 " received (not a response). "
			"Dropping the MAD.\n", key);

		return OSMV_ROUTE_DROP;
	}

	return OSMV_ROUTE_SIMPLE;
}
Example #3
0
/**********************************************************************
 * TS RCV Thread callback
 * HACK: - we need to make this support arbitrary size mads.
 **********************************************************************/
void
__osm_ts_rcv_callback(IN osm_ts_bind_info_t * p_bind,
		      IN osm_mad_addr_t * p_mad_addr,
		      IN uint32_t mad_size, IN void *p_mad)
{
	ib_api_status_t status;
	osm_madw_t *p_req_madw = NULL;
	osm_madw_t *p_madw;
	osm_vend_wrap_t *p_new_vw;
	ib_mad_t *p_mad_buf;
	osm_log_t *const p_log = p_bind->p_vend->p_log;

	OSM_LOG_ENTER(p_log);

	/* if it is a response MAD we mustbe able to get the request */
	if (ib_mad_is_response((ib_mad_t *) p_mad)) {
		/* can we find a matching madw by this payload TID */
		status =
		    osm_transaction_mgr_get_madw_for_tid(p_bind->p_vend,
							 (ib_mad_t *) p_mad,
							 &p_req_madw);
		if (status != IB_SUCCESS) {
			osm_log(p_log, OSM_LOG_ERROR,
				"__osm_ts_rcv_callback: ERR 5008: "
				"Error obtaining request madw by TID (%d).\n",
				status);
			p_req_madw = NULL;
		}

		if (p_req_madw == NULL) {
			osm_log(p_log, OSM_LOG_ERROR,
				"__osm_ts_rcv_callback: ERR 5009:  "
				"Fail to obtain request madw for receined MAD. Aborting CB.\n");
			goto Exit;
		}
	}

	/* do we have a request ??? */
	if (p_req_madw == NULL) {

		/* if not - get new osm_madw and arrange it. */
		/* create the new madw in the pool */
		p_madw = osm_mad_pool_get(p_bind->p_osm_pool,
					  (osm_bind_handle_t) p_bind,
					  mad_size, p_mad_addr);
		if (p_madw == NULL) {
			osm_log(p_log, OSM_LOG_ERROR,
				"__osm_ts_rcv_callback: ERR 5010: "
				"Error request for a new madw.\n");
			goto Exit;
		}
		/* HACK: we cust to avoid the const ??? */
		p_mad_buf = (void *)p_madw->p_mad;
	} else {
		/* we have the madw defined during the send and stored in the vend_wrap */
		/* we need to make sure the wrapper is correctly init there */
		CL_ASSERT(p_req_madw->vend_wrap.p_resp_madw != 0);
		p_madw = p_req_madw->vend_wrap.p_resp_madw;

		CL_ASSERT(p_madw->h_bind);
		p_mad_buf =
		    osm_vendor_get(p_madw->h_bind, mad_size,
				   &p_madw->vend_wrap);

		if (p_mad_buf == NULL) {
			osm_log(p_log, OSM_LOG_ERROR,
				"__osm_ts_rcv_callback: ERR 5011: "
				"Unable to acquire wire MAD.\n");

			goto Exit;
		}

		/*
		   Finally, attach the wire MAD to this wrapper.
		 */
		osm_madw_set_mad(p_madw, p_mad_buf);
	}

	/* init some fields of the vendor wrapper */
	p_new_vw = osm_madw_get_vend_ptr(p_madw);
	p_new_vw->h_bind = p_bind;
	p_new_vw->size = mad_size;
	p_new_vw->p_resp_madw = NULL;
	p_new_vw->p_mad_buf = p_mad_buf;

	memcpy(p_new_vw->p_mad_buf, p_mad, mad_size);

	/* attach the buffer to the wrapper */
	p_madw->p_mad = p_mad_buf;

	/* we can also make sure we marked the size and bind on the returned madw */
	p_madw->h_bind = p_new_vw->h_bind;

	/* call the CB */
	(*(osm_vend_mad_recv_callback_t) p_bind->rcv_callback)
	    (p_madw, p_bind->client_context, p_req_madw);

Exit:
	OSM_LOG_EXIT(p_log);
}
Example #4
0
static void
__osm_al_rcv_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem)
{
	osm_al_bind_info_t *const p_bind =
	    (osm_al_bind_info_t *) mad_svc_context;
	osm_vendor_t *const p_vend = p_bind->p_vend;
	osm_madw_t *p_old_madw;
	osm_madw_t *p_new_madw;
	osm_vend_wrap_t *p_old_vw;
	osm_vend_wrap_t *p_new_vw;
	ib_mad_t *p_new_mad;
	osm_mad_addr_t mad_addr;

	OSM_LOG_ENTER(p_vend->p_log);

	CL_ASSERT(p_elem->context1 == NULL);
	CL_ASSERT(p_elem->context2 == NULL);

	p_new_mad = ib_get_mad_buf(p_elem);

	/*
	   In preperation for initializing the new mad wrapper,
	   Initialize the mad_addr structure for the received wire MAD.
	 */
	mad_addr.dest_lid = p_elem->remote_lid;
	mad_addr.path_bits = p_elem->path_bits;

	/* TO DO - figure out which #define to use for the 2.5 Gb rate... */
	mad_addr.static_rate = 0;

	if (p_new_mad->mgmt_class == IB_MCLASS_SUBN_LID ||
	    p_new_mad->mgmt_class == IB_MCLASS_SUBN_DIR) {
		mad_addr.addr_type.smi.source_lid = p_elem->remote_lid;
	} else {
		mad_addr.addr_type.gsi.remote_qp = p_elem->remote_qp;
		mad_addr.addr_type.gsi.remote_qkey = p_elem->remote_qkey;
		mad_addr.addr_type.gsi.pkey_ix = p_elem->pkey_index;
		mad_addr.addr_type.gsi.service_level = p_elem->remote_sl;
		mad_addr.addr_type.gsi.global_route = FALSE;
	}

	/*
	   If this MAD is a response to a previous request,
	   then grab our pre-allocated MAD wrapper.
	   Otherwise, allocate a new MAD wrapper.
	 */
	if (ib_mad_is_response(p_new_mad)) {
		CL_ASSERT(p_elem->send_context1 != NULL);
		CL_ASSERT(p_elem->send_context2 == NULL);

		p_old_madw = (osm_madw_t *) p_elem->send_context1;
		p_old_vw = osm_madw_get_vend_ptr(p_old_madw);
		p_new_madw = p_old_vw->p_resp_madw;

		CL_ASSERT(p_new_madw);

		osm_madw_init(p_new_madw, p_bind, p_elem->size, &mad_addr);
		osm_madw_set_mad(p_new_madw, p_new_mad);
	} else {
		CL_ASSERT(p_elem->send_context1 == NULL);
		CL_ASSERT(p_elem->send_context2 == NULL);

		p_new_madw = osm_mad_pool_get_wrapper(p_bind->p_osm_pool,
						      p_bind, p_elem->size,
						      p_new_mad, &mad_addr);
	}

	CL_ASSERT(p_new_madw);
	p_new_vw = osm_madw_get_vend_ptr(p_new_madw);

	p_new_vw->h_bind = p_bind;
	p_new_vw->size = p_elem->size;
	p_new_vw->p_elem = p_elem;
	p_new_vw->h_av = 0;
	p_new_vw->p_resp_madw = NULL;

	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
		"__osm_al_rcv_callback: "
		"Calling receive callback function %p.\n",
		p_bind->rcv_callback);

	p_bind->rcv_callback(p_new_madw, p_bind->client_context,
			     p_elem->send_context1);

	OSM_LOG_EXIT(p_vend->p_log);
}