Пример #1
0
DAT_RETURN
dapl_cr_query(
	IN DAT_CR_HANDLE cr_handle,
	IN DAT_CR_PARAM_MASK cr_param_mask,
	OUT DAT_CR_PARAM *cr_param)
{
	DAPL_CR	*cr_ptr;
	DAT_RETURN dat_status;

	dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_cr_query (%p, %x, %p)\n",
	    cr_handle, cr_param_mask, cr_param);

	dat_status = DAT_SUCCESS;
	if (DAPL_BAD_HANDLE(cr_handle, DAPL_MAGIC_CR)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_CR);
		goto bail;
	}

	if (NULL == cr_param) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER,
		    DAT_INVALID_ARG3);
		goto bail;
	}

	cr_ptr = (DAPL_CR *) cr_handle;

	/* since the arguments are easily accessible, ignore the mask */
	(void) dapl_os_memcpy(cr_param, &cr_ptr->param, sizeof (DAT_CR_PARAM));

bail:
	return (dat_status);
}
Пример #2
0
/*
 * dapl_ep_recv_query
 *
 * uDAPL Version 1.2, 6.6.11
 *
 * Destroy an instance of the Endpoint
 *
 * Input:
 *	ep_handle
 *
 * Output:
 *	none
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_PARAMETER
 *	DAT_INVALID_HANDLE
 *	DAT_MODEL_NOT_SUPPORTED
 */
DAT_RETURN DAT_API
dapl_ep_recv_query(IN DAT_EP_HANDLE ep_handle,
		   OUT DAT_COUNT * nbufs_allocate,
		   OUT DAT_COUNT * bufs_alloc_span)
{
	DAPL_EP *ep_ptr;
	DAT_RETURN dat_status;

	dat_status = DAT_SUCCESS;

	dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_ep_recv_query (%p, %p, %p)\n",
		     ep_handle, nbufs_allocate, bufs_alloc_span);

	ep_ptr = (DAPL_EP *) ep_handle;

	/*
	 * Verify parameter & state
	 */
	if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
		goto bail;
	}

	dat_status = DAT_ERROR(DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);

      bail:
	return dat_status;

}
Пример #3
0
/*
 * dapl_cno_query
 *
 * DAPL Requirements Version xxx, 6.3.2.5
 *
 * Return the consumer parameters of the CNO
 *
 * Input:
 *	cno_handle
 *	cno_param_mask
 *	cno_param
 *
 * Output:
 *	cno_param
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_HANDLE
 *	DAT_INVALID_PARAMETER
 */
DAT_RETURN
dapl_cno_query(
	IN	DAT_CNO_HANDLE		cno_handle,	/* cno_handle */
	IN	DAT_CNO_PARAM_MASK	cno_param_mask,	/* cno_param_mask */
	OUT	DAT_CNO_PARAM 		*cno_param)	/* cno_param */
{
	DAPL_CNO	 *cno_ptr;
	DAT_RETURN   dat_status;

	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(cno_handle, DAPL_MAGIC_CNO)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_CNO);
		goto bail;
	}

	/* check for invalid cno param mask */
	if (cno_param_mask & ~DAT_CNO_FIELD_ALL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
		goto bail;
	}

	if (NULL == cno_param) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
		goto bail;
	}

	cno_ptr = (DAPL_CNO *)cno_handle;
	cno_param->ia_handle = cno_ptr->header.owner_ia;
	cno_param->agent = cno_ptr->cno_wait_agent;

bail:
	return (dat_status);
}
Пример #4
0
/*
 * dapl_evd_set_unwaitable
 *
 * DAPL Requirements Version 1.1, 6.3.4.7
 *
 * Transition the Event Dispatcher into an unwaitable state
 *
 * Input:
 * 	evd_handle
 *
 * Output:
 *	none
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_HANDLE
 */
DAT_RETURN DAT_API dapl_evd_set_unwaitable(IN DAT_EVD_HANDLE evd_handle)
{
	DAPL_EVD *evd_ptr;
	DAT_RETURN dat_status;

	evd_ptr = (DAPL_EVD *) evd_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD))
	{
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);
		goto bail;
	}
	dapl_os_lock(&evd_ptr->header.lock);
	evd_ptr->evd_waitable = DAT_FALSE;

	/*
	 * If this evd is waiting, wake it up. There is an obvious race
	 * condition here where we may wakeup the waiter before it goes to
	 * sleep; but the wait_object allows this and will do the right
	 * thing.
	 */
	if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED) {
		if (evd_ptr->evd_flags & (DAT_EVD_DTO_FLAG | DAT_EVD_RMR_BIND_FLAG))
			dapls_evd_dto_wakeup(evd_ptr);
		else
			dapl_os_wait_object_wakeup(&evd_ptr->wait_object);
	}
	dapl_os_unlock(&evd_ptr->header.lock);
      bail:
	return dat_status;
}
Пример #5
0
/*
 * dapl_ep_query
 *
 * DAPL Requirements Version xxx, 6.5.5
 *
 * Provide the consumer parameters, including attributes and status of
 * the Endpoint.
 *
 * Input:
 *	ep_handle
 *	ep_param_mask
 *
 * Output:
 *	ep_param
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_PARAMETER
 */
DAT_RETURN DAT_API
dapl_ep_query(IN DAT_EP_HANDLE ep_handle,
	      IN DAT_EP_PARAM_MASK ep_param_mask, OUT DAT_EP_PARAM * ep_param)
{
	DAPL_EP *ep_ptr;
	DAT_RETURN dat_status;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
		     "dapl_ep_query (%p, %x, %p)\n",
		     ep_handle, ep_param_mask, ep_param);

	dat_status = DAT_SUCCESS;
	ep_ptr = (DAPL_EP *) ep_handle;

	/*
	 * Verify parameter & state
	 */
	if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP);
		goto bail;
	}

	if (ep_param == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
		goto bail;
	}

	/*
	 * Fill in according to user request
	 *
	 * N.B. Just slam all values into the user structure, there
	 *      is nothing to be gained by checking for each bit.
	 */
	if (ep_param_mask & DAT_EP_FIELD_ALL) {
		/* only attempt to get remote IA address if consumer requested it */
		if (ep_param_mask & DAT_EP_FIELD_REMOTE_IA_ADDRESS_PTR) {
			if (ep_ptr->param.ep_state == DAT_EP_STATE_CONNECTED) {
				/* obtain the remote IP address */
				dat_status =
				    dapls_ib_cm_remote_addr((DAT_HANDLE)
							    ep_handle,
							    &ep_ptr->
							    remote_ia_address);
			}
			ep_ptr->param.remote_ia_address_ptr =
			    (DAT_IA_ADDRESS_PTR) & ep_ptr->remote_ia_address;
		}
		*ep_param = ep_ptr->param;
		dats_get_ia_handle(ep_ptr->param.ia_handle, &ep_param->ia_handle);
	}

      bail:
	return dat_status;
}
Пример #6
0
/*
 * dapl_rmr_bind
 *
 * DAPL Requirements Version xxx, 6.6.4.4
 *
 * Bind the RMR to the specified memory region within the LMR and
 * provide a new rmr_context value.
 *
 * Input:
 * Output:
 */
DAT_RETURN
dapl_rmr_bind(
	IN	DAT_RMR_HANDLE		rmr_handle,
	IN	const DAT_LMR_TRIPLET	*lmr_triplet,
	IN	DAT_MEM_PRIV_FLAGS	mem_priv,
	IN	DAT_EP_HANDLE		ep_handle,
	IN	DAT_RMR_COOKIE		user_cookie,
	IN	DAT_COMPLETION_FLAGS 	completion_flags,
	OUT	DAT_RMR_CONTEXT		*rmr_context)
{
	DAPL_RMR				*rmr;
	DAPL_EP 				*ep_ptr;

	if (DAPL_BAD_HANDLE(rmr_handle, DAPL_MAGIC_RMR)) {
		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_RMR));
	}
	if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {
		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));
	}

	rmr = (DAPL_RMR *) rmr_handle;
	ep_ptr = (DAPL_EP *) ep_handle;

	/* if the rmr should be bound */
	if (0 != lmr_triplet->segment_length) {
		return (dapli_rmr_bind_fuse(rmr,
		    lmr_triplet,
		    mem_priv,
		    ep_ptr,
		    user_cookie,
		    completion_flags,
		    rmr_context));
	} else { /* the rmr should be unbound */
		return (dapli_rmr_bind_unfuse(rmr,
		    lmr_triplet,
		    ep_ptr,
		    user_cookie,
		    completion_flags));
	}
}
Пример #7
0
DAT_RETURN
dapl_ep_dup_connect(
	IN DAT_EP_HANDLE ep_handle,
	IN DAT_EP_HANDLE ep_dup_handle,
	IN DAT_TIMEOUT timeout,
	IN DAT_COUNT private_data_size,
	IN const DAT_PVOID private_data,
	IN DAT_QOS qos)
{
	DAPL_EP *ep_dup_ptr;
	DAT_RETURN dat_status;
	DAT_IA_ADDRESS_PTR remote_ia_address_ptr;
	DAT_CONN_QUAL remote_conn_qual;

	ep_dup_ptr = (DAPL_EP *)ep_dup_handle;

	/*
	 * Verify the dup handle, which must be connected. All other
	 * parameters will be verified by dapl_ep_connect
	 */
	if (DAPL_BAD_HANDLE(ep_dup_handle, DAPL_MAGIC_EP)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EP);
		goto bail;
	}
	/*
	 * Check both the EP state and the QP state: if we don't have a QP
	 *  there is a problem.  Do this under a lock and pull out
	 * the connection parameters for atomicity.
	 */
	dapl_os_lock(&ep_dup_ptr->header.lock);
	if (ep_dup_ptr->param.ep_state != DAT_EP_STATE_CONNECTED) {
		dapl_os_unlock(&ep_dup_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_STATE,
		    dapls_ep_state_subtype(ep_dup_ptr));
		goto bail;
	}
	remote_ia_address_ptr = ep_dup_ptr->param.remote_ia_address_ptr;
	remote_conn_qual = ep_dup_ptr->param.remote_port_qual;
	dapl_os_unlock(&ep_dup_ptr->header.lock);

	dat_status = dapl_ep_connect(ep_handle,
	    remote_ia_address_ptr, remote_conn_qual, timeout,
	    private_data_size, private_data, qos,
	    DAT_CONNECT_DEFAULT_FLAG);

bail:
	return (dat_status);
}
Пример #8
0
/*
 * dapl_cno_create
 *
 * DAPL Requirements Version xxx, 6.3.4.1
 *
 * Create a consumer notification object instance
 *
 * Input:
 *	ia_handle
 *	wait_agent
 *	cno_handle
 *
 * Output:
 *	cno_handle
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INSUFFICIENT_RESOURCES
 *	DAT_INVALID_HANDLE
 *	DAT_INVALID_PARAMETER
 */
DAT_RETURN dapl_cno_create(
	IN	DAT_IA_HANDLE			ia_handle,	/* ia_handle */
	IN	DAT_OS_WAIT_PROXY_AGENT		wait_agent,	/* agent */
	OUT	DAT_CNO_HANDLE			*cno_handle)	/* cno_handle */

{
	DAPL_IA		*ia_ptr;
	DAPL_CNO	*cno_ptr;
	DAT_RETURN	dat_status;

	ia_ptr = (DAPL_IA *)ia_handle;
	cno_ptr = NULL;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(ia_handle, DAPL_MAGIC_IA)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_IA);
		goto bail;
	}

	cno_ptr = dapl_cno_alloc(ia_ptr, wait_agent);

	if (!cno_ptr) {
		dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
		    DAT_RESOURCE_MEMORY);
		goto bail;
	}

	cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED;

	dat_status = dapls_ib_cno_alloc(ia_ptr, cno_ptr);
	if (dat_status != DAT_SUCCESS) {
		goto bail;
	}

	dapl_ia_link_cno(ia_ptr, cno_ptr);

	*cno_handle = cno_ptr;

bail:
	if (dat_status != DAT_SUCCESS && cno_ptr != NULL) {
		dapl_cno_dealloc(cno_ptr);
	}
	return (dat_status);
}
Пример #9
0
/*
 * dapl_cno_free
 *
 * DAPL Requirements Version xxx, 6.3.2.2
 *
 * Destroy a consumer notification object instance
 *
 * Input:
 *	cno_handle
 *
 * Output:
 *	none
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_HANDLE
 *	DAT_INVALID_STATE
 */
DAT_RETURN
dapl_cno_free(
	IN	DAT_CNO_HANDLE		cno_handle)	/* cno_handle */
{
	DAPL_CNO    *cno_ptr;
	DAT_RETURN  dat_status;

	dat_status = DAT_SUCCESS;
	cno_ptr = (DAPL_CNO *)cno_handle;

	if (DAPL_BAD_HANDLE(cno_handle, DAPL_MAGIC_CNO)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_CNO);
		goto bail;
	}

	if (cno_ptr->cno_ref_count != 0 || cno_ptr->cno_waiters != 0) {
		dat_status = DAT_ERROR(DAT_INVALID_STATE,
		    DAT_INVALID_STATE_CNO_IN_USE);
		goto bail;
	}

	dapl_os_lock(&cno_ptr->header.lock);
	if (!dapl_llist_is_empty(&cno_ptr->evd_list_head)) {
		dapl_dbg_log(DAPL_DBG_TYPE_UTIL,
		    "cno_free: evd list not empty!\n");
		dapl_os_unlock(&cno_ptr->header.lock);
		dat_status =  DAT_ERROR(DAT_INVALID_STATE,
		    DAT_INVALID_STATE_CNO_IN_USE);
		goto bail;
	}
	dapl_os_unlock(&cno_ptr->header.lock);

	dat_status = dapls_ib_cno_free(cno_ptr);
	if (dat_status != DAT_SUCCESS) {
		goto bail;
	}

	dapl_ia_unlink_cno(cno_ptr->header.owner_ia, cno_ptr);
	dapl_cno_dealloc(cno_ptr);

bail:
	return (dat_status);
}
Пример #10
0
DAT_RETURN DAT_API dapl_evd_disable(IN DAT_EVD_HANDLE evd_handle)
{
	DAPL_EVD *evd_ptr;
	DAT_RETURN dat_status;

	evd_ptr = (DAPL_EVD *) evd_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD))
	{
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);
		goto bail;
	}

	evd_ptr->evd_enabled = DAT_FALSE;

      bail:
	return dat_status;
}
Пример #11
0
DAT_RETURN
dapl_cr_handoff(
	IN DAT_CR_HANDLE cr_handle,
	IN DAT_CONN_QUAL cr_handoff)		/* handoff */
{
	DAPL_CR *cr_ptr;
	DAT_RETURN dat_status;

	if (DAPL_BAD_HANDLE(cr_handle, DAPL_MAGIC_CR)) {
		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_CR));
	}

	cr_ptr = (DAPL_CR *)cr_handle;
	dat_status = dapls_ib_handoff_connection(cr_ptr, cr_handoff);

	/* Remove the CR from the queue, then free it */
	dapl_sp_remove_cr(cr_ptr->sp_ptr, cr_ptr);
	dapls_cr_free(cr_ptr);

	return (dat_status);
}
Пример #12
0
/*
 * dapl_pz_query
 *
 * DAPL Requirements Version xxx, 6.6.2.1
 *
 * Return the ia associated with the protection zone pz
 *
 * Input:
 * 	pz_handle
 *      pz_param_mask
 *
 * Output:
 * 	pz_param
 *
 * Returns:
 * 	DAT_SUCCESS
 *      DAT_INVALID_HANDLE
 * 	DAT_INVALID_PARAMETER
 */
DAT_RETURN
dapl_pz_query(
	IN	DAT_PZ_HANDLE		pz_handle,
	IN	DAT_PZ_PARAM_MASK	pz_param_mask,
	OUT	DAT_PZ_PARAM		*pz_param)
{
	DAPL_PZ		*pz;
	DAT_RETURN	dat_status;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
	    "dapl_pz_query (%p, %x, %p)\n",
	    pz_handle,
	    pz_param_mask,
	    pz_param);

	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(pz_handle, DAPL_MAGIC_PZ)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_PZ);
		goto bail;
	}
	if (NULL == pz_param) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
		goto bail;
	}
	if (pz_param_mask & ~DAT_PZ_FIELD_ALL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
		goto bail;
	}

	pz = (DAPL_PZ *) pz_handle;

	/* Since the DAT_PZ_ARGS values are easily accessible, */
	/* don't bother checking the DAT_PZ_ARGS_MASK value    */
	pz_param->ia_handle = (DAT_IA_HANDLE) pz->header.owner_ia;

bail:
	return (dat_status);
}
Пример #13
0
/*
 * dapl_rmr_free
 *
 * DAPL Requirements Version xxx, 6.6.4.2
 *
 * Destroy an instance of the Remote Memory Region
 *
 * Input:
 * 	rmr_handle
 *
 * Output:
 * 	none
 *
 * Returns:
 * 	DAT_SUCCESS
 * 	DAT_INVALID_PARAMETER
 */
DAT_RETURN
dapl_rmr_free(IN DAT_RMR_HANDLE rmr_handle)
{
	DAPL_RMR *rmr;
	DAT_RETURN dat_status;

	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(rmr_handle, DAPL_MAGIC_RMR)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_RMR);
		goto bail;
	}

	rmr = (DAPL_RMR *)rmr_handle;

	/*
	 * If the user did not perform an unbind op, release
	 * counts here.
	 */
	if (rmr->param.lmr_triplet.virtual_address != 0) {
		(void) dapl_os_atomic_dec(&rmr->lmr->lmr_ref_count);
		rmr->param.lmr_triplet.virtual_address = 0;
	}

	dat_status = dapls_ib_mw_free(rmr);

	if (dat_status != DAT_SUCCESS) {
		goto bail;
	}

	dapl_os_atomic_dec(&rmr->pz->pz_ref_count);

	dapl_rmr_dealloc(rmr);

bail:
	return (dat_status);
}
Пример #14
0
/*
 * dapl_srq_query
 *
 * DAPL Requirements Version 1.2, 6.5.6
 *
 * Return SRQ parameters to the consumer
 *
 * Input:
 * 	srq_handle
 *      srq_param_mask
 *
 * Output:
 * 	srq_param
 *
 * Returns:
 * 	DAT_SUCCESS
 *      DAT_INVALID_HANDLE
 * 	DAT_INVALID_PARAMETER
 */
DAT_RETURN DAT_API
dapl_srq_query(IN DAT_SRQ_HANDLE srq_handle,
	       IN DAT_SRQ_PARAM_MASK srq_param_mask,
	       OUT DAT_SRQ_PARAM * srq_param)
{
	DAPL_SRQ *srq_ptr;
	DAT_RETURN dat_status;

	dat_status = DAT_SUCCESS;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
		     "dapl_srq_query (%p, %x, %p)\n",
		     srq_handle, srq_param_mask, srq_param);

	if (DAPL_BAD_HANDLE(srq_handle, DAPL_MAGIC_SRQ)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_SRQ);
		goto bail;
	}
	if (srq_param == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
		goto bail;
	}

	srq_ptr = (DAPL_SRQ *) srq_handle;

	/*
	 * XXX Need to calculate available_dto_count and outstanding_dto_count
	 */
	srq_ptr->param.available_dto_count = DAT_VALUE_UNKNOWN;
	srq_ptr->param.outstanding_dto_count = DAT_VALUE_UNKNOWN;

	*srq_param = srq_ptr->param;
	dats_get_ia_handle(srq_ptr->header.owner_ia, &srq_param->ia_handle);

      bail:
	return dat_status;
}
Пример #15
0
DAT_RETURN DAT_API dapl_evd_create(IN DAT_IA_HANDLE ia_handle,
                                   IN DAT_COUNT evd_min_qlen,
                                   IN DAT_CNO_HANDLE cno_handle,
                                   IN DAT_EVD_FLAGS evd_flags,
                                   OUT DAT_EVD_HANDLE * evd_handle)
{
    DAPL_IA *ia_ptr;
    DAPL_EVD *evd_ptr;
    DAPL_CNO *cno_ptr;
    DAT_RETURN dat_status;
    DAT_PROVIDER_ATTR provider_attr;
    int i;
    int j;
    int flag_mask[6];

    dapl_dbg_log(DAPL_DBG_TYPE_API,
                 "dapl_evd_create (%p, %d, %p, 0x%x, %p)\n",
                 ia_handle,
                 evd_min_qlen, cno_handle, evd_flags, evd_handle);

    ia_ptr = (DAPL_IA *) ia_handle;
    cno_ptr = (DAPL_CNO *) cno_handle;
    evd_ptr = NULL;
    *evd_handle = NULL;
    dat_status = DAT_SUCCESS;

    if (DAPL_BAD_HANDLE(ia_handle, DAPL_MAGIC_IA)) {
        dat_status =
            DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
        goto bail;
    }

    DAPL_CNTR(ia_ptr, DCNT_IA_EVD_CREATE);

    if (evd_min_qlen <= 0) {
        dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
        goto bail;
    }
    if (evd_min_qlen > ia_ptr->hca_ptr->ia_attr.max_evd_qlen) {
        dat_status =
            DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_TEVD);
        goto bail;
    }

    if (cno_handle != DAT_HANDLE_NULL
            && DAPL_BAD_HANDLE(cno_handle, DAPL_MAGIC_CNO)) {
        dat_status =
            DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_CNO);
        goto bail;
    }

    /*
     * Check the merging attributes to ensure the combination of
     * flags requested is supported.
     */
    dapl_ia_query(ia_handle, NULL,
                  0, NULL, DAT_PROVIDER_FIELD_ALL, &provider_attr);

    /* Set up an array of flags to compare against; the EVD bits are
     * a sparse array that need to be mapped to the merging flags
     */
    flag_mask[0] = DAT_EVD_SOFTWARE_FLAG;
    flag_mask[1] = DAT_EVD_CR_FLAG;
    flag_mask[2] = DAT_EVD_DTO_FLAG;
    flag_mask[3] = DAT_EVD_CONNECTION_FLAG;
    flag_mask[4] = DAT_EVD_RMR_BIND_FLAG;
    flag_mask[5] = DAT_EVD_ASYNC_FLAG;

    for (i = 0; i < 6; i++) {
        if (flag_mask[i] & evd_flags) {
            for (j = 0; j < 6; j++) {
                if (flag_mask[j] & evd_flags) {
                    if (provider_attr.
                            evd_stream_merging_supported[i][j]
                            == DAT_FALSE) {
                        dat_status =
                            DAT_ERROR
                            (DAT_INVALID_PARAMETER,
                             DAT_INVALID_ARG4);
                        goto bail;
                    }
                }
            }	/* end for j */
        }
    }			/* end for i */

    dat_status = dapls_evd_internal_create(ia_ptr,
                                           cno_ptr,
                                           evd_min_qlen,
                                           evd_flags, &evd_ptr);
    if (dat_status != DAT_SUCCESS) {
        goto bail;
    }

    evd_ptr->evd_state = DAPL_EVD_STATE_OPEN;

    *evd_handle = (DAT_EVD_HANDLE) evd_ptr;

bail:
    if (dat_status != DAT_SUCCESS) {
        if (evd_ptr) {
            dapl_evd_free(evd_ptr);
        }
    }

    dapl_dbg_log(DAPL_DBG_TYPE_RTN,
                 "dapl_evd_create () returns 0x%x\n", dat_status);

    return dat_status;
}
Пример #16
0
/*
 * dapl_ia_open
 *
 * DAPL Requirements Version xxx, 6.2.1.1
 *
 * Open a provider and return a handle. The handle enables the user
 * to invoke operations on this provider.
 *
 * The dat_ia_open  call is actually part of the DAT registration module.
 * That function maps the DAT_NAME parameter of dat_ia_open to a DAT_PROVIDER,
 * and calls this function.
 *
 * Input:
 *	provider
 *	async_evd_qlen
 *	async_evd_handle_ptr
 *
 * Output:
 *	async_evd_handle
 *	ia_handle
 *
 * Return Values:
 * 	DAT_SUCCESS
 * 	DAT_INSUFFICIENT_RESOURCES
 * 	DAT_INVALID_PARAMETER
 * 	DAT_INVALID_HANDLE
 * 	DAT_PROVIDER_NOT_FOUND	(returned by dat registry if necessary)
 */
DAT_RETURN DAT_API
dapl_ia_open(IN const DAT_NAME_PTR name,
	     IN DAT_COUNT async_evd_qlen,
	     INOUT DAT_EVD_HANDLE * async_evd_handle_ptr,
	     OUT DAT_IA_HANDLE * ia_handle_ptr)
{
	DAT_RETURN dat_status;
	DAT_PROVIDER *provider;
	DAPL_HCA *hca_ptr;
	DAPL_IA *ia_ptr;
	DAPL_EVD *evd_ptr;

	dat_status = DAT_SUCCESS;
	hca_ptr = NULL;
	ia_ptr = NULL;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
		     "dapl_ia_open (%s, %d, %p, %p)\n",
		     name, async_evd_qlen, async_evd_handle_ptr, ia_handle_ptr);

	dat_status = dapl_provider_list_search(name, &provider);
	if (DAT_SUCCESS != dat_status) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1);
		goto bail;
	}

	/* ia_handle_ptr and async_evd_handle_ptr cannot be NULL */
	if (ia_handle_ptr == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
		goto bail;
	}
	if (async_evd_handle_ptr == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
		goto bail;
	}

	/* initialize the caller's OUT param */
	*ia_handle_ptr = DAT_HANDLE_NULL;

	/* get the hca_ptr */
	hca_ptr = (DAPL_HCA *) provider->extension;

	/* log levels could be reset and set between opens */
	g_dapl_dbg_type =  dapl_os_get_env_val("DAPL_DBG_TYPE",
				     	       DAPL_DBG_TYPE_ERR |
				     	       DAPL_DBG_TYPE_WARN);
	/*
	 * Open the HCA if it has not been done before.
	 */
	dapl_os_lock(&hca_ptr->lock);
	if (hca_ptr->ib_hca_handle == IB_INVALID_HANDLE) {
		/* register with the HW */
		dat_status = dapls_ib_open_hca(hca_ptr->name, hca_ptr, DAPL_OPEN_NORMAL);

		if (dat_status != DAT_SUCCESS) {
			dapl_dbg_log(DAPL_DBG_TYPE_ERR,
				     "dapls_ib_open_hca failed %x\n",
				     dat_status);
			dapl_os_unlock(&hca_ptr->lock);
			goto bail;
		}

		/*
		 * Obtain the IP address associated with this name and HCA.
		 */
#ifdef IBHOSTS_NAMING
		dapli_assign_hca_ip_address(hca_ptr, name);
#endif				/* IBHOSTS_NAMING */

		/*
		 * Obtain IA attributes from the HCA to limit certain
		 * operations.
		 * If using DAPL_ATS naming, ib_query_hca will also set the ip
		 * address.
		 */
		dat_status = dapls_ib_query_hca(hca_ptr,
						&hca_ptr->ia_attr,
						NULL, &hca_ptr->hca_address);
		if (dat_status != DAT_SUCCESS) {
			dapli_hca_cleanup(hca_ptr, DAT_FALSE);
			dapl_os_unlock(&hca_ptr->lock);
			goto bail;
		}
	}

	/* Take a reference on the hca_handle */
	dapl_os_atomic_inc(&hca_ptr->handle_ref_count);
	dapl_os_unlock(&hca_ptr->lock);

	/* Allocate and initialize ia structure */
	ia_ptr = dapl_ia_alloc(provider, hca_ptr);
	if (!ia_ptr) {
		dapl_os_lock(&hca_ptr->lock);
		dapli_hca_cleanup(hca_ptr, DAT_TRUE);
		dapl_os_unlock(&hca_ptr->lock);
		dat_status =
		    DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
		goto bail;
	}

	/* we need an async EVD for this IA
	 * use the one passed in (if non-NULL) or create one
	 */

	evd_ptr = (DAPL_EVD *) * async_evd_handle_ptr;
	if (evd_ptr) {
		if (DAPL_BAD_HANDLE(evd_ptr, DAPL_MAGIC_EVD) ||
		    !(evd_ptr->evd_flags & DAT_EVD_ASYNC_FLAG)) {
			dat_status =
			    DAT_ERROR(DAT_INVALID_HANDLE,
				      DAT_INVALID_HANDLE_EVD_ASYNC);
			goto bail;
		}

		/* InfiniBand allows only 1 asychronous event handler per HCA */
		/* (see InfiniBand Spec, release 1.1, vol I, section 11.5.2,  */
		/*  page 559).                                                */
		/*                                                            */
		/* We only need to make sure that this EVD's CQ belongs to    */
		/* the same HCA as is being opened.                           */

		if (evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle !=
		    hca_ptr->ib_hca_handle) {
			dat_status =
			    DAT_ERROR(DAT_INVALID_HANDLE,
				      DAT_INVALID_HANDLE_EVD_ASYNC);
			goto bail;
		}

		ia_ptr->cleanup_async_error_evd = DAT_FALSE;
		ia_ptr->async_error_evd = evd_ptr;
	} else {
		/* Verify we have >0 length, and let the provider check the size */
		if (async_evd_qlen <= 0) {
			dat_status =
			    DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
			goto bail;
		}
		dat_status = dapls_evd_internal_create(ia_ptr, NULL,	/* CNO ptr */
						       async_evd_qlen,
						       DAT_EVD_ASYNC_FLAG,
						       &evd_ptr);
		if (dat_status != DAT_SUCCESS) {
			goto bail;
		}

		dapl_os_atomic_inc(&evd_ptr->evd_ref_count);

		dapl_os_lock(&hca_ptr->lock);
		if (hca_ptr->async_evd != (DAPL_EVD *) 0) {
			dapl_os_unlock(&hca_ptr->lock);
		} else {
			hca_ptr->async_evd = evd_ptr;
			dapl_os_unlock(&hca_ptr->lock);

			/* Register the handlers associated with the async EVD.  */
			dat_status = dapls_ia_setup_callbacks(ia_ptr, evd_ptr);
			if (dat_status != DAT_SUCCESS) {
				/* Assign the EVD so it gets cleaned up */
				ia_ptr->cleanup_async_error_evd = DAT_TRUE;
				ia_ptr->async_error_evd = evd_ptr;
				goto bail;
			}
		}

		ia_ptr->cleanup_async_error_evd = DAT_TRUE;
		ia_ptr->async_error_evd = evd_ptr;
	}

	dat_status = DAT_SUCCESS;
	*ia_handle_ptr = ia_ptr;
	*async_evd_handle_ptr = evd_ptr;

#if DAPL_COUNTERS
	dapli_start_counters((DAT_HANDLE)ia_ptr);
#endif

      bail:
	if (dat_status != DAT_SUCCESS) {
		if (ia_ptr) {
			/* This will release the async EVD if needed.  */
			dapl_ia_close(ia_ptr, DAT_CLOSE_ABRUPT_FLAG);
		}
	}

	dapl_dbg_log(DAPL_DBG_TYPE_RTN,
		     "dapl_ia_open () returns 0x%x\n", dat_status);

	return dat_status;
}
Пример #17
0
/*
 * dapl_psp_create
 *
 * uDAPL: User Direct Access Program Library Version 1.1, 6.4.1.1
 *
 * Create a persistent Public Service Point that can recieve multiple
 * requests for connections and generate multiple connection request
 * instances that wil be delivered to the specified Event Dispatcher
 * in a notification event.
 *
 * Input:
 * 	ia_handle
 * 	conn_qual
 * 	evd_handle
 * 	psp_flags
 *
 * Output:
 * 	psp_handle
 *
 * Returns:
 * 	DAT_SUCCESS
 * 	DAT_INSUFFICIENT_RESOURCES
 * 	DAT_INVALID_PARAMETER
 * 	DAT_CONN_QUAL_IN_USE
 * 	DAT_MODEL_NOT_SUPPORTED
 */
DAT_RETURN
dapl_psp_create(
	IN DAT_IA_HANDLE	   ia_handle,
	IN DAT_CONN_QUAL	   conn_qual,
	IN DAT_EVD_HANDLE	   evd_handle,
	IN DAT_PSP_FLAGS	   psp_flags,
	OUT DAT_PSP_HANDLE	   *psp_handle)
{
	DAPL_IA	*ia_ptr;
	DAPL_SP	*sp_ptr;
	DAPL_EVD *evd_ptr;
	DAT_BOOLEAN sp_found;
	DAT_RETURN dat_status;

	ia_ptr = (DAPL_IA *)ia_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_IA);
		goto bail;
	}

	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	if (psp_handle == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
		goto bail;
	}

	/* check for invalid psp flags */
	if ((psp_flags != DAT_PSP_CONSUMER_FLAG) &&
	    (psp_flags != DAT_PSP_PROVIDER_FLAG)) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
		goto bail;
	}

	evd_ptr = (DAPL_EVD *)evd_handle;
	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	/*
	 * check for connection qualifier eq 0
	 * in IB this is called Null Service ID, use of it in CM is invalid.
	 * in tcp/udp, port number 0 is reserved.
	 */
	if (!conn_qual) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
		goto bail;
	}

	/*
	 * See if we have a quiescent listener to use for this PSP, else
	 * create one and set it listening
	 */
	sp_ptr = dapls_ia_sp_search(ia_ptr, conn_qual, DAT_TRUE);
	sp_found = DAT_TRUE;
	if (sp_ptr == NULL) {
		/* Allocate PSP */
		sp_found = DAT_FALSE;
		sp_ptr   = dapls_sp_alloc(ia_ptr, DAT_TRUE);

		if (sp_ptr == NULL) {
			dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
			    DAT_RESOURCE_MEMORY);
			goto bail;
		}
	} else if (sp_ptr->listening == DAT_TRUE) {
		dat_status = DAT_ERROR(DAT_CONN_QUAL_IN_USE, 0);
		goto bail;
	}

	/*
	 * Fill out the args for a PSP
	 */
	sp_ptr->ia_handle  = ia_handle;
	sp_ptr->conn_qual  = conn_qual;
	sp_ptr->evd_handle = evd_handle;
	sp_ptr->psp_flags  = psp_flags;
	sp_ptr->ep_handle  = NULL;

	/*
	 * Take a reference on the EVD handle
	 */
	(void) dapl_os_atomic_inc(&((DAPL_EVD *)evd_handle)->evd_ref_count);

	/*
	 * Set up a listener for a connection. Connections can arrive
	 * even before this call returns!
	 */
	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
	sp_ptr->listening = DAT_TRUE;

	/*
	 * If this is a new sp we need to add it to the IA queue, and set up
	 * a conn_listener.
	 */
	if (sp_found == DAT_FALSE) {

		/* Link it onto the IA */
		dapl_ia_link_psp(ia_ptr, sp_ptr);

		dat_status = dapls_ib_setup_conn_listener(ia_ptr, conn_qual,
		    sp_ptr);

		if (dat_status != DAT_SUCCESS) {
			/*
			 * Have a problem setting up the connection, something
			 * wrong!  The psp_free decrements the EVD refcount for
			 * us; we don't * need to do that.
			 * But we want to set the listener bits to false,
			 * as we know that call failed.
			 */
			sp_ptr->state = DAPL_SP_STATE_FREE;
			sp_ptr->listening = DAT_FALSE;
			(void) dapl_psp_free((DAT_PSP_HANDLE) sp_ptr);

			dapl_dbg_log(DAPL_DBG_TYPE_CM,
			    "--> dapl_psp_create setup_conn_listener failed: "
			    "%x\n",
			    dat_status);

			goto bail;
		}
	}

	/*
	 * Return handle to the user
	 */
	*psp_handle = (DAT_PSP_HANDLE)sp_ptr;

bail:
	return (dat_status);
}
Пример #18
0
/*
 * dapl_ep_connect
 *
 * DAPL Requirements Version xxx, 6.5.7
 *
 * Request a connection be established between the local Endpoint
 * and a remote Endpoint. This operation is used by the active/client
 * side of a connection
 *
 * Input:
 *	ep_handle
 *	remote_ia_address
 *	remote_conn_qual
 *	timeout
 *	private_data_size
 *	privaet_data
 *	qos
 *	connect_flags
 *
 * Output:
 *	None
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INSUFFICIENT_RESOUCRES
 *	DAT_INVALID_PARAMETER
 *	DAT_MODLE_NOT_SUPPORTED
 */
DAT_RETURN
dapl_ep_connect(
	IN DAT_EP_HANDLE ep_handle,
	IN DAT_IA_ADDRESS_PTR remote_ia_address,
	IN DAT_CONN_QUAL remote_conn_qual,
	IN DAT_TIMEOUT timeout,
	IN DAT_COUNT private_data_size,
	IN const DAT_PVOID private_data,
	IN DAT_QOS qos,
	IN DAT_CONNECT_FLAGS connect_flags)
{
	DAPL_EP *ep_ptr;
	DAPL_PRIVATE prd;
	DAPL_EP	alloc_ep;
	DAT_RETURN dat_status;

	dapl_dbg_log(DAPL_DBG_TYPE_API | DAPL_DBG_TYPE_CM,
	    "dapl_ep_connect (%p, {%u.%u.%u.%u}, %X, %d, %d, %p, %x, %x)\n",
	    ep_handle,
	    remote_ia_address->sa_data[2],
	    remote_ia_address->sa_data[3],
	    remote_ia_address->sa_data[4],
	    remote_ia_address->sa_data[5],
	    remote_conn_qual,
	    timeout,
	    private_data_size,
	    private_data,
	    qos,
	    connect_flags);

	dat_status = DAT_SUCCESS;
	ep_ptr = (DAPL_EP *) ep_handle;

	/*
	 * Verify parameter & state. The connection handle must be good
	 * at this point.
	 */
	if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EP);
		goto bail;
	}

	if (DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EVD_CONN);
		goto bail;
	}

	/*
	 * If the endpoint needs a QP, associated the QP with it.
	 * This needs to be done carefully, in order to:
	 *	* Avoid allocating under a lock.
	 *  * Not step on data structures being altered by
	 *    routines with which we are racing.
	 * So we:
	 *  * Confirm that a new QP is needed and is not forbidden by the
	 *    current state.
	 *  * Allocate it into a separate EP.
	 *  * Take the EP lock.
	 *  * Reconfirm that the EP is in a state where it needs a QP.
	 *  * Assign the QP and release the lock.
	 */
	if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
		if (ep_ptr->param.pz_handle == NULL ||
		    DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ)) {
			dat_status = DAT_ERROR(DAT_INVALID_STATE,
			    DAT_INVALID_STATE_EP_NOTREADY);
			goto bail;
		}
		alloc_ep = *ep_ptr;

		dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
		    &alloc_ep, ep_ptr);
		if (dat_status != DAT_SUCCESS) {
			dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
			    DAT_RESOURCE_MEMORY);
			goto bail;
		}

		dapl_os_lock(&ep_ptr->header.lock);
		/*
		 * PZ shouldn't have changed since we're only racing with
		 * dapl_cr_accept()
		 */
		if (ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED) {
			/* Bail, cleaning up.  */
			dapl_os_unlock(&ep_ptr->header.lock);
			dat_status = dapls_ib_qp_free(ep_ptr->header.owner_ia,
			    &alloc_ep);
			if (dat_status != DAT_SUCCESS) {
				dapl_dbg_log(DAPL_DBG_TYPE_WARN,
				    "ep_connect: ib_qp_free failed with %x\n",
				    dat_status);
			}
			dat_status = DAT_ERROR(DAT_INVALID_STATE,
			    dapls_ep_state_subtype(ep_ptr));
			goto bail;
		}
		ep_ptr->qp_handle = alloc_ep.qp_handle;
		ep_ptr->qpn = alloc_ep.qpn;
		ep_ptr->qp_state = alloc_ep.qp_state;

		dapl_os_unlock(&ep_ptr->header.lock);
	}

	/*
	 * We do state checks and transitions under lock.
	 * The only code we're racing against is dapl_cr_accept.
	 */
	dapl_os_lock(&ep_ptr->header.lock);

	/*
	 * Verify the attributes of the EP handle before we connect it. Test
	 * all of the handles to make sure they are currently valid.
	 * Specifically:
	 *   pz_handle		required
	 *   recv_evd_handle	optional, but must be valid
	 *   request_evd_handle	optional, but must be valid
	 *   connect_evd_handle	required
	 */
	if (ep_ptr->param.pz_handle == NULL ||
	    DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ) ||
	    ep_ptr->param.connect_evd_handle == NULL ||
	    DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle,
	    DAPL_MAGIC_EVD) ||
	    !(((DAPL_EVD *)ep_ptr->param.connect_evd_handle)->evd_flags &
	    DAT_EVD_CONNECTION_FLAG) ||
	    (ep_ptr->param.recv_evd_handle != DAT_HANDLE_NULL &&
	    (DAPL_BAD_HANDLE(ep_ptr->param.recv_evd_handle,
	    DAPL_MAGIC_EVD))) ||
	    (ep_ptr->param.request_evd_handle != DAT_HANDLE_NULL &&
	    (DAPL_BAD_HANDLE(ep_ptr->param.request_evd_handle,
	    DAPL_MAGIC_EVD)))) {
		dapl_os_unlock(&ep_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_STATE,
		    DAT_INVALID_STATE_EP_NOTREADY);
		goto bail;
	}

	/*
	 * Check both the EP state and the QP state: if we don't have a QP
	 *  we need to attach one now.
	 */
	if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
		dat_status = dapls_ib_qp_alloc(ep_ptr->header.owner_ia,
		    ep_ptr, ep_ptr);

		if (dat_status != DAT_SUCCESS) {
			dapl_os_unlock(&ep_ptr->header.lock);
			dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
			    DAT_RESOURCE_TEP);
			goto bail;
		}
	}

	if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED) {
		dapl_os_unlock(&ep_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_STATE,
		    dapls_ep_state_subtype(ep_ptr));
		goto bail;
	}

	if (qos != DAT_QOS_BEST_EFFORT ||
	    connect_flags != DAT_CONNECT_DEFAULT_FLAG) {
		/*
		 * At this point we only support one QOS level
		 */
		dapl_os_unlock(&ep_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_MODEL_NOT_SUPPORTED, 0);
		goto bail;
	}

	/*
	 * Verify the private data size doesn't exceed the max
	 */
	if (private_data_size > DAPL_CONSUMER_MAX_PRIVATE_DATA_SIZE) {
		dapl_os_unlock(&ep_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
		goto bail;
	}

	/*
	 * transition the state before requesting a connection to avoid
	 * race conditions
	 */
	ep_ptr->param.ep_state = DAT_EP_STATE_ACTIVE_CONNECTION_PENDING;

	/*
	 * At this point we're committed, and done with the endpoint
	 * except for the connect, so we can drop the lock.
	 */
	dapl_os_unlock(&ep_ptr->header.lock);

	/*
	 * fill in the private data
	 */
	(void) dapl_os_memzero(&prd, sizeof (DAPL_PRIVATE));
	if (private_data_size > 0)
		(void) dapl_os_memcpy(prd.private_data, private_data,
		    private_data_size);

	/* Copy the connection qualifiers */
	(void) dapl_os_memcpy(ep_ptr->param.remote_ia_address_ptr,
	    remote_ia_address, sizeof (DAT_SOCK_ADDR6));
	ep_ptr->param.remote_port_qual = remote_conn_qual;

	dat_status = dapls_ib_connect(ep_handle,
	    remote_ia_address, remote_conn_qual,
	    private_data_size, &prd, timeout);

	if (dat_status != DAT_SUCCESS) {
		DAPL_EVD	*evd_ptr;

		if (dat_status == DAT_ERROR(DAT_INVALID_ADDRESS,
		    DAT_INVALID_ADDRESS_UNREACHABLE)) {
			/* Unreachable IP address */
			evd_ptr = (DAPL_EVD *)ep_ptr->param.connect_evd_handle;
			if (evd_ptr != NULL) {
				(void) dapls_evd_post_connection_event(evd_ptr,
				    DAT_CONNECTION_EVENT_UNREACHABLE,
				    (DAT_HANDLE) ep_ptr, 0, 0);
			}
			ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
			dat_status = DAT_SUCCESS;
		} else if (dat_status == DAT_ERROR(DAT_INVALID_PARAMETER,
		    DAT_INVALID_ADDRESS_UNREACHABLE)) {
			/* Non-existant connection qualifier */
			evd_ptr = (DAPL_EVD *)ep_ptr->param.connect_evd_handle;
			if (evd_ptr != NULL) {
				(void) dapls_evd_post_connection_event(evd_ptr,
				    DAT_CONNECTION_EVENT_NON_PEER_REJECTED,
				    (DAT_HANDLE) ep_ptr, 0, 0);
			}
			ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
			dat_status = DAT_SUCCESS;
		} else {
			ep_ptr->param.ep_state = DAT_EP_STATE_UNCONNECTED;
		}
	}

bail:
	dapl_dbg_log(DAPL_DBG_TYPE_RTN | DAPL_DBG_TYPE_CM,
	    "dapl_ep_connect () returns 0x%x\n", dat_status);

	return (dat_status);
}
Пример #19
0
/*
 * dapl_psp_create_any
 *
 * uDAPL: User Direct Access Program Library Version 1.1, 6.4.3.3
 *
 * Create a persistent Public Service Point that can receive multiple
 * requests for connections and generate multiple connection request
 * instances that will be delivered to the specified Event Dispatcher
 * in a notification event. Differs from dapl_psp_create() in that
 * the conn_qual is selected by the implementation and returned to
 * the user.
 *
 * Input:
 * 	ia_handle
 * 	evd_handle
 * 	psp_flags
 *
 * Output:
 * 	conn_qual
 * 	psp_handle
 *
 * Returns:
 * 	DAT_SUCCESS
 * 	DAT_INSUFFICIENT_RESOURCES
 * 	DAT_INVALID_HANDLE
 * 	DAT_INVALID_PARAMETER
 * 	DAT_CONN_QUAL_IN_USE
 * 	DAT_MODEL_NOT_SUPPORTED
 */
DAT_RETURN DAT_API
dapl_psp_create_any(IN DAT_IA_HANDLE ia_handle,
		    OUT DAT_CONN_QUAL * conn_qual,
		    IN DAT_EVD_HANDLE evd_handle,
		    IN DAT_PSP_FLAGS psp_flags, OUT DAT_PSP_HANDLE * psp_handle)
{
	DAPL_IA *ia_ptr;
	DAPL_SP *sp_ptr;
	DAPL_EVD *evd_ptr;
	DAT_RETURN dat_status;
	static DAT_CONN_QUAL hint_conn_qual = 1024;	/* seed value */
	DAT_CONN_QUAL lcl_conn_qual;
	DAT_CONN_QUAL limit_conn_qual;

	ia_ptr = (DAPL_IA *) ia_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
		goto bail;
	}
	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	if (psp_handle == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
		goto bail;
	}
	if (conn_qual == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
		goto bail;
	}

	evd_ptr = (DAPL_EVD *) evd_handle;
	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	if (psp_flags != DAT_PSP_CONSUMER_FLAG &&
	    psp_flags != DAT_PSP_PROVIDER_FLAG) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
		goto bail;
	}

	/* Allocate PSP */
	sp_ptr = dapls_sp_alloc(ia_ptr, DAT_TRUE);
	if (sp_ptr == NULL) {
		dat_status =
		    DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY);
		goto bail;
	}

	DAPL_CNTR(ia_ptr, DCNT_IA_PSP_CREATE_ANY);

	/*
	 * Fill out the args for a PSP
	 */
	sp_ptr->evd_handle = evd_handle;
	sp_ptr->psp_flags = psp_flags;
	sp_ptr->ep_handle = NULL;

	/*
	 * Take a reference on the EVD handle
	 */
	dapl_os_atomic_inc(&((DAPL_EVD *) evd_handle)->evd_ref_count);

	/* Link it onto the IA */
	dapl_ia_link_psp(ia_ptr, sp_ptr);

	/* 
	 * Set up a listener for a connection. Connections can arrive
	 * even before this call returns!
	 */
	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
	sp_ptr->listening = DAT_TRUE;

	limit_conn_qual = 0;
	lcl_conn_qual = hint_conn_qual;
	dat_status = ~DAT_SUCCESS;

	while (dat_status != DAT_SUCCESS) {
		dat_status = dapls_ib_setup_conn_listener(ia_ptr,
							  lcl_conn_qual,
							  sp_ptr);

		lcl_conn_qual++;

		if (dat_status == DAT_CONN_QUAL_IN_USE) {
			/*
			 * If we have a big number of tries and we still haven't
			 * found a service_ID we can use, bail out with an error,
			 * something is wrong!
			 */
			if (limit_conn_qual++ > 100000) {
				dat_status = DAT_CONN_QUAL_UNAVAILABLE;
				break;
			}
		}
	}
	hint_conn_qual = lcl_conn_qual;

	if (dat_status != DAT_SUCCESS) {
		/*
		 * Have a problem setting up the connection, something wrong!
		 */
		dapl_os_atomic_dec(&((DAPL_EVD *) evd_handle)->evd_ref_count);
		sp_ptr->evd_handle = NULL;
		dapls_ia_unlink_sp(ia_ptr, sp_ptr);
		dapls_sp_free_sp(sp_ptr);

		dapl_os_printf
		    ("--> dapl_psp_create cannot set up conn listener: %x\n",
		     dat_status);

		goto bail;
	}

	sp_ptr->conn_qual = lcl_conn_qual - 1;

	/*
	 * Return handle to the user
	 */
	*conn_qual = sp_ptr->conn_qual;
	*psp_handle = (DAT_PSP_HANDLE) sp_ptr;

      bail:
	return dat_status;
}
Пример #20
0
/*
 * dapli_get_sp_ep
 *
 * Passive side of a connection is now fully established. Clean
 * up resources and obtain the EP pointer associated with a CR in
 * the SP
 *
 * Input:
 * 	ib_cm_handle,
 * 	sp_ptr
 *	connection_event
 *
 * Output:
 *	none
 *
 * Returns
 * 	ep_ptr
 *
 */
DAPL_EP *dapli_get_sp_ep(IN dp_ib_cm_handle_t ib_cm_handle,
			 IN DAPL_SP * sp_ptr, IN DAT_EVENT_NUMBER dat_event_num)
{
	DAPL_CR *cr_ptr;
	DAPL_EP *ep_ptr;

	/*
	 * acquire the lock, we may be racing with other threads here
	 */
	dapl_os_lock(&sp_ptr->header.lock);

	/* Verify under lock that the SP is still valid */
	if (sp_ptr->header.magic == DAPL_MAGIC_INVALID) {
		dapl_os_unlock(&sp_ptr->header.lock);
		return NULL;
	}
	/*
	 * There are potentially multiple connections in progress. Need to
	 * go through the list and find the one we are interested
	 * in. There is no guarantee of order. dapl_sp_search_cr
	 * leaves the CR on the SP queue.
	 */
	cr_ptr = dapl_sp_search_cr(sp_ptr, ib_cm_handle);
	if (cr_ptr == NULL) {
		dapl_os_unlock(&sp_ptr->header.lock);
		return NULL;
	}

	ep_ptr = (DAPL_EP *) cr_ptr->param.local_ep_handle;

	/* Quick check to ensure our EP is still valid */
	if ((DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP))) {
		ep_ptr = NULL;
	}

	/* The CR record is discarded in all except for the CONNECTED case,
	 * as it will have no further relevance.
	 */
	if (dat_event_num != DAT_CONNECTION_EVENT_ESTABLISHED) {
		/* Remove the CR from the queue */
		dapl_sp_remove_cr(sp_ptr, cr_ptr);

		if (ep_ptr != NULL) {
			ep_ptr->cr_ptr = NULL;
		}

		/*
		 * If this SP has been removed from service, free it
		 * up after the last CR is removed
		 */
		if (sp_ptr->listening != DAT_TRUE && sp_ptr->cr_list_count == 0
		    && sp_ptr->state != DAPL_SP_STATE_FREE
		    && sp_ptr->state != DAPL_SP_STATE_RSP_LISTENING) {
			dapl_dbg_log(DAPL_DBG_TYPE_CM,
				     "--> dapli_get_sp_ep! disconnect dump sp: %p \n",
				     sp_ptr);
			/* Decrement the ref count on the EVD */
			if (sp_ptr->evd_handle) {
				dapl_os_atomic_dec(&
						   ((DAPL_EVD *) sp_ptr->
						    evd_handle)->evd_ref_count);
				sp_ptr->evd_handle = NULL;
			}
			sp_ptr->state = DAPL_SP_STATE_FREE;
			dapl_os_unlock(&sp_ptr->header.lock);
			(void)dapls_ib_remove_conn_listener(sp_ptr->header.
							    owner_ia, sp_ptr);
			dapls_ia_unlink_sp((DAPL_IA *) sp_ptr->header.owner_ia,
					   sp_ptr);
			dapls_sp_free_sp(sp_ptr);
			dapls_cr_free(cr_ptr);
			goto skip_unlock;
		}

		dapl_os_unlock(&sp_ptr->header.lock);
		/* free memory outside of the lock */
		dapls_cr_free(cr_ptr);
	} else {
		dapl_os_unlock(&sp_ptr->header.lock);
	}

      skip_unlock:
	return ep_ptr;
}
Пример #21
0
DAT_RETURN dapl_evd_resize(
	IN	DAT_EVD_HANDLE	   evd_handle,
	IN	DAT_COUNT	   req_evd_qlen)
{
	int			i;
	DAPL_EVD		*evd_ptr;
	DAT_EVENT		*event_ptr;
	DAT_EVENT		*eventp;
	DAT_EVENT		*event;
	DAT_EVENT		*new_event;
	DAPL_RING_BUFFER	free_event_queue;
	DAPL_RING_BUFFER	pending_event_queue;
	DAT_RETURN		dat_status;
	DAT_COUNT		max_evd_qlen;
	DAT_COUNT		evd_qlen;

	evd_ptr = (DAPL_EVD *)evd_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		return (DAT_ERROR(DAT_INVALID_HANDLE, 0));
	}

	if (req_evd_qlen < evd_ptr->qlen) {
		return (DAT_ERROR(DAT_INVALID_STATE, 0));
	}

	if (req_evd_qlen == evd_ptr->qlen) {
		return (DAT_SUCCESS);
	}

	max_evd_qlen = evd_ptr->header.owner_ia->hca_ptr->ia_attr.max_evd_qlen;
	if (req_evd_qlen > max_evd_qlen) {
		return (DAT_ERROR(DAT_INVALID_STATE, 0));
	}

	evd_qlen = DAPL_MIN_RESZ_QLEN;
	while (req_evd_qlen > evd_qlen) {
		evd_qlen <<= 1;
		if (evd_qlen > max_evd_qlen)
			evd_qlen = max_evd_qlen;
	}

	/* Allocate EVENTs */
	event_ptr = (DAT_EVENT *) dapl_os_alloc(evd_qlen * sizeof (DAT_EVENT));
	if (!event_ptr) {
		return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
		    DAT_RESOURCE_MEMORY));
	}

	/* allocate free event queue */
	dat_status = dapls_rbuf_alloc(&free_event_queue, evd_qlen);
	if (dat_status != DAT_SUCCESS) {
		goto bail;
	}

	/* allocate pending event queue */
	dat_status = dapls_rbuf_alloc(&pending_event_queue, evd_qlen);
	if (dat_status != DAT_SUCCESS) {
		goto bail;
	}

	/* need to resize the cq only for DTO/BIND evds */
	if (0 != (evd_ptr->evd_flags & ~ (DAT_EVD_SOFTWARE_FLAG |
	    DAT_EVD_CONNECTION_FLAG | DAT_EVD_CR_FLAG))) {
		dat_status = dapls_ib_cq_resize(evd_ptr, evd_qlen);
		if (dat_status != DAT_SUCCESS)
			goto bail;
	}

	/* add events to free event queue */
	for (i = 0, eventp = event_ptr; i < evd_qlen; i++) {
		(void) dapls_rbuf_add(&free_event_queue, (void *)eventp);
		eventp++;
	}
	/*
	 * copy pending events from evd to the new pending event queue
	 */
	while (event = (DAT_EVENT *)
	    dapls_rbuf_remove(&evd_ptr->pending_event_queue)) {
		new_event = (DAT_EVENT *) dapls_rbuf_remove(&free_event_queue);
		dapl_os_assert(new_event);
		(void) dapl_os_memcpy(new_event, event, sizeof (DAT_EVENT));
		dat_status = dapls_rbuf_add(&pending_event_queue, new_event);
		dapl_os_assert(dat_status == DAT_SUCCESS);
		dat_status = dapls_rbuf_add(&evd_ptr->free_event_queue, event);
		dapl_os_assert(dat_status == DAT_SUCCESS);
	}

	dapls_rbuf_destroy(&evd_ptr->free_event_queue);
	dapls_rbuf_destroy(&evd_ptr->pending_event_queue);
	if (evd_ptr->events) {
		dapl_os_free(evd_ptr->events,
		    evd_ptr->qlen * sizeof (DAT_EVENT));
	}
	evd_ptr->events = event_ptr;
	evd_ptr->free_event_queue = free_event_queue;
	evd_ptr->pending_event_queue = pending_event_queue;
	evd_ptr->qlen = evd_qlen;

	return (DAT_SUCCESS);
bail:
	/*
	 * If we are here means event_ptr was allocd but something else
	 * failed
	 */
	dapl_os_free(event_ptr, evd_qlen * sizeof (DAT_EVENT));
	dapls_rbuf_destroy(&free_event_queue);
	dapls_rbuf_destroy(&pending_event_queue);

	return (dat_status);
}
Пример #22
0
/*
 * dapl_psp_create
 *
 * uDAPL: User Direct Access Program Library Version 1.1, 6.4.1.1
 *
 * Create a persistent Public Service Point that can receive multiple
 * requests for connections and generate multiple connection request
 * instances that will be delivered to the specified Event Dispatcher
 * in a notification event.
 *
 * Input:
 * 	ia_handle
 * 	conn_qual
 * 	evd_handle
 * 	psp_flags
 *
 * Output:
 * 	psp_handle
 *
 * Returns:
 * 	DAT_SUCCESS
 * 	DAT_INSUFFICIENT_RESOURCES
 * 	DAT_INVALID_PARAMETER
 * 	DAT_CONN_QUAL_IN_USE
 * 	DAT_MODEL_NOT_SUPPORTED
 */
DAT_RETURN DAT_API
dapl_psp_create(IN DAT_IA_HANDLE ia_handle,
		IN DAT_CONN_QUAL conn_qual,
		IN DAT_EVD_HANDLE evd_handle,
		IN DAT_PSP_FLAGS psp_flags, OUT DAT_PSP_HANDLE * psp_handle)
{
	DAPL_IA *ia_ptr;
	DAPL_SP *sp_ptr;
	DAPL_EVD *evd_ptr;
	DAT_BOOLEAN sp_found;
	DAT_RETURN dat_status;

	ia_ptr = (DAPL_IA *) ia_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
		goto bail;
	}
	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	if (psp_handle == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
		goto bail;
	}

	evd_ptr = (DAPL_EVD *) evd_handle;
	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	if (psp_flags != DAT_PSP_CONSUMER_FLAG &&
	    psp_flags != DAT_PSP_PROVIDER_FLAG) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
		goto bail;
	}

	DAPL_CNTR(ia_ptr, DCNT_IA_PSP_CREATE);

	/*
	 * See if we have a quiescent listener to use for this PSP, else
	 * create one and set it listening
	 */
	sp_ptr = dapls_ia_sp_search(ia_ptr, conn_qual, DAT_TRUE);
	sp_found = DAT_TRUE;
	if (sp_ptr == NULL) {
		/* Allocate PSP */
		sp_found = DAT_FALSE;
		sp_ptr = dapls_sp_alloc(ia_ptr, DAT_TRUE);
		if (sp_ptr == NULL) {
			dat_status =
			    DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
				      DAT_RESOURCE_MEMORY);
			goto bail;
		}
	} else if (sp_ptr->listening == DAT_TRUE) {
		dat_status = DAT_ERROR(DAT_CONN_QUAL_IN_USE, 0);
		goto bail;
	}

	/*
	 * Fill out the args for a PSP
	 */
	sp_ptr->conn_qual = conn_qual;
	sp_ptr->evd_handle = evd_handle;
	sp_ptr->psp_flags = psp_flags;
	sp_ptr->ep_handle = NULL;

	/*
	 * Take a reference on the EVD handle
	 */
	dapl_os_atomic_inc(&((DAPL_EVD *) evd_handle)->evd_ref_count);

	/* 
	 * Set up a listener for a connection. Connections can arrive
	 * even before this call returns!
	 */
	sp_ptr->state = DAPL_SP_STATE_PSP_LISTENING;
	sp_ptr->listening = DAT_TRUE;

	/*
	 * If this is a new sp we need to add it to the IA queue, and set up
	 * a conn_listener.
	 */
	if (sp_found == DAT_FALSE) {
		/* Link it onto the IA before enabling it to receive conn
		 * requests
		 */
		dapl_ia_link_psp(ia_ptr, sp_ptr);

		dat_status = dapls_ib_setup_conn_listener(ia_ptr,
							  conn_qual, sp_ptr);

		if (dat_status != DAT_SUCCESS) {
			/*
			 * Have a problem setting up the connection, something
			 * wrong!  Decrements the EVD refcount & release it.
			 */
			dapl_os_atomic_dec(&((DAPL_EVD *) evd_handle)->
					   evd_ref_count);
			sp_ptr->evd_handle = NULL;
			dapls_ia_unlink_sp(ia_ptr, sp_ptr);
			dapls_sp_free_sp(sp_ptr);

			dapl_dbg_log(DAPL_DBG_TYPE_CM,
				     "--> dapl_psp_create setup_conn_listener failed: %x\n",
				     dat_status);

			goto bail;
		}
	}

	/*
	 * Return handle to the user
	 */
	*psp_handle = (DAT_PSP_HANDLE) sp_ptr;

      bail:
	return dat_status;
}
Пример #23
0
/*
 * dapl_cr_accept
 *
 * DAPL Requirements Version xxx, 6.4.2.1
 *
 * Establish a connection between active remote side requesting Endpoint
 * and passic side local Endpoint.
 *
 * Input:
 *	cr_handle
 *	ep_handle
 *	private_data_size
 *	private_data
 *
 * Output:
 *	none
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_PARAMETER
 *	DAT_INVALID_ATTRIBUTE
 */
DAT_RETURN
dapl_cr_accept(
	IN	DAT_CR_HANDLE		cr_handle,
	IN	DAT_EP_HANDLE		ep_handle,
	IN	DAT_COUNT		private_data_size,
	IN	const DAT_PVOID		private_data)
{
	DAPL_EP		*ep_ptr;
	DAT_RETURN	dat_status;
	DAPL_PRIVATE	prd;
	DAPL_CR		*cr_ptr;
	DAT_EP_STATE	entry_ep_state;
	DAT_EP_HANDLE	entry_ep_handle;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
	    "dapl_cr_accept(%p, %p, %d, %p)\n",
	    cr_handle, ep_handle, private_data_size, private_data);

	if (DAPL_BAD_HANDLE(cr_handle, DAPL_MAGIC_CR)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_CR);
		goto bail;
	}

	cr_ptr = (DAPL_CR *) cr_handle;

	/*
	 * Return an error if we have an ep_handle and the CR already has an
	 * EP, indicating this is an RSP connection or PSP_PROVIDER_FLAG was
	 * specified.
	 */
	if (ep_handle != NULL &&
	    (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP) ||
	    cr_ptr->param.local_ep_handle != NULL)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EP);
		goto bail;
	}

	if ((0 != private_data_size) && (NULL == private_data)) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
		goto bail;
	}

	/*
	 * Verify the private data size doesn't exceed the max
	 */
	if (private_data_size > DAPL_CONSUMER_MAX_PRIVATE_DATA_SIZE) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
		goto bail;
	}

	/*
	 * ep_handle is NULL if the user specified DAT_PSP_PROVIDER_FLAG
	 * OR this is an RSP connection; retrieve it from the cr.
	 */
	if (ep_handle == NULL) {
		ep_handle = cr_ptr->param.local_ep_handle;
		if ((((DAPL_EP *) ep_handle)->param.ep_state !=
		    DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING) &&
		    (((DAPL_EP *)ep_handle)->param.ep_state !=
		    DAT_EP_STATE_PASSIVE_CONNECTION_PENDING)) {
			return (DAT_INVALID_STATE);
		}
	} else {
		/* ensure this EP isn't connected or in use */
		if (((DAPL_EP *)ep_handle)->param.ep_state !=
		    DAT_EP_STATE_UNCONNECTED) {
			return (DAT_INVALID_STATE);
		}
	}

	ep_ptr = (DAPL_EP *) ep_handle;

	/*
	 * Verify the attributes of the EP handle before we connect it. Test
	 * all of the handles to make sure they are currently valid.
	 * Specifically:
	 *   pz_handle		required
	 *   recv_evd_handle	optional, but must be valid
	 *   request_evd_handle	optional, but must be valid
	 *   connect_evd_handle	required
	 * We do all verification and state change under lock, at which
	 * point the EP state should protect us from most races.
	 */
	dapl_os_lock(&ep_ptr->header.lock);
	if ((ep_ptr->param.pz_handle == NULL) ||
	    DAPL_BAD_HANDLE(ep_ptr->param.pz_handle, DAPL_MAGIC_PZ) ||
	    (ep_ptr->param.connect_evd_handle == NULL) ||
	    DAPL_BAD_HANDLE(ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD) ||
	    !(((DAPL_EVD *)ep_ptr->param.connect_evd_handle)->evd_flags &
	    DAT_EVD_CONNECTION_FLAG) ||
	    (ep_ptr->param.recv_evd_handle != DAT_HANDLE_NULL &&
	    (DAPL_BAD_HANDLE(ep_ptr->param.recv_evd_handle, DAPL_MAGIC_EVD))) ||
	    (ep_ptr->param.request_evd_handle != DAT_HANDLE_NULL &&
	    (DAPL_BAD_HANDLE(ep_ptr->param.request_evd_handle,
	    DAPL_MAGIC_EVD)))) {
		dapl_os_unlock(&ep_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EP);
		goto bail;
	}

	if (ep_ptr->qp_state == DAPL_QP_STATE_UNATTACHED) {
		/*
		 * If we are lazy attaching the QP then we may need to
		 * hook it up here. Typically, we run this code only for
		 * DAT_PSP_PROVIDER_FLAG
		 */
		dat_status = dapls_ib_qp_alloc(cr_ptr->header.owner_ia, ep_ptr,
		    ep_ptr);

		if (dat_status != DAT_SUCCESS) {
			/* This is not a great error code, but spec allows */
			dapl_os_unlock(&ep_ptr->header.lock);
			dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
			    DAT_INVALID_HANDLE_EP);
			goto bail;
		}
	}

	entry_ep_state = ep_ptr->param.ep_state;
	entry_ep_handle = cr_ptr->param.local_ep_handle;
	ep_ptr->param.ep_state = DAT_EP_STATE_COMPLETION_PENDING;
	ep_ptr->cm_handle = cr_ptr->ib_cm_handle;
	ep_ptr->cr_ptr = cr_ptr;
	ep_ptr->param.remote_ia_address_ptr = cr_ptr->param.
	    remote_ia_address_ptr;
	cr_ptr->param.local_ep_handle = ep_handle;

	/*
	 * private data
	 */
	(void) dapl_os_memcpy(prd.private_data, private_data,
	    private_data_size);
	(void) dapl_os_memzero(prd.private_data + private_data_size,
	    sizeof (DAPL_PRIVATE) - private_data_size);

	dapl_os_unlock(&ep_ptr->header.lock);

	dat_status = dapls_ib_accept_connection(cr_handle, ep_handle, &prd);

	/*
	 * If the provider failed, unwind the damage so we are back at
	 * the initial state.
	 */
	if (dat_status != DAT_SUCCESS) {
		ep_ptr->param.ep_state = entry_ep_state;
		cr_ptr->param.local_ep_handle = entry_ep_handle;
	} else {
		/*
		 * Make this CR invalid. We need to hang on to it until
		 * the connection terminates, but it's destroyed from
		 * the app point of view.
		 */
		cr_ptr->header.magic = DAPL_MAGIC_CR_DESTROYED;
	}

bail:
	return (dat_status);
}
Пример #24
0
DAT_RETURN dapl_evd_dequeue(
    IN    DAT_EVD_HANDLE	evd_handle,
    OUT   DAT_EVENT		*event)
{
	DAPL_EVD	*evd_ptr;
	DAT_EVENT	*local_event;
	DAT_RETURN	dat_status;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
	    "dapl_evd_dequeue (%p, %p)\n",
	    evd_handle,
	    event);

	evd_ptr = (DAPL_EVD *)evd_handle;
	dat_status = DAT_SUCCESS;

	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE, 0);
		goto bail;
	}

	if (event == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
		goto bail;
	}

	/*
	 * We need to dequeue under lock, as the IB OS Access API
	 * restricts us from having multiple threads in CQ poll, and the
	 * DAPL 1.1 API allows multiple threads in dat_evd_dequeue()
	 */
	dapl_os_lock(&evd_ptr->header.lock);

	/*
	 * Make sure there are no other waiters and the evd is active.
	 * Currently this means only the OPEN state is allowed.
	 */
	if (evd_ptr->evd_state != DAPL_EVD_STATE_OPEN ||
	    evd_ptr->catastrophic_overflow) {
		dapl_os_unlock(&evd_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);
		goto bail;
	}

	/*
	 * Try the EVD rbuf first; poll from the CQ only if that's empty.
	 * This keeps events in order if dat_evd_wait() has copied events
	 * from CQ to EVD.
	 */
	if (evd_ptr->pending_event_queue.head !=
	    evd_ptr->pending_event_queue.tail) {
		local_event = (DAT_EVENT *)
		    dapls_rbuf_remove(&evd_ptr->pending_event_queue);
		if (local_event != NULL) {
			*event = *local_event;
			dat_status = dapls_rbuf_add(&evd_ptr->free_event_queue,
			    local_event);
		} else { /* should never happen */
			dat_status = DAT_ERROR(DAT_INTERNAL_ERROR, 0);
		}
	} else if (evd_ptr->ib_cq_handle == IB_INVALID_HANDLE) {
		dat_status =  DAT_ERROR(DAT_QUEUE_EMPTY, 0);
	} else if ((evd_ptr->evd_flags & (DAT_EVD_CONNECTION_FLAG |
	    DAT_EVD_CR_FLAG | DAT_EVD_ASYNC_FLAG)) == 0) {
		/*
		 * No need to drop into kernel, just check the CQ.
		 */
		dat_status = dapls_evd_cq_poll_to_event(evd_ptr, event);
	} else {
		/* poll for events with threshold and timeout both 0 */
		evd_ptr->threshold = 0;

		dapl_os_unlock(&evd_ptr->header.lock);
		dat_status = dapls_evd_copy_events(evd_ptr, 0);
		if (dat_status != DAT_SUCCESS) {
			dat_status = DAT_ERROR(DAT_QUEUE_EMPTY, 0);
			goto bail;
		}

		dapl_os_lock(&evd_ptr->header.lock);

		local_event = (DAT_EVENT *)dapls_rbuf_remove(
		    &evd_ptr->pending_event_queue);
		if (local_event != NULL) {
			*event = *local_event;
			dat_status = dapls_rbuf_add(&evd_ptr->free_event_queue,
			    local_event);
		} else { /* still didn't find anything */
			dat_status =  DAT_ERROR(DAT_QUEUE_EMPTY, 0);
		}
	}

	dapl_os_unlock(&evd_ptr->header.lock);
bail:
	dapl_dbg_log(DAPL_DBG_TYPE_RTN,
	    "dapl_evd_dequeue () returns 0x%x\n",
	    dat_status);

	return (dat_status);
}
Пример #25
0
/*
 * dapl_rsp_create
 *
 * uDAPL: User Direct Access Program Library Version 1.1, 6.4.3.4.1
 *
 * Create a Resereved Service Point with the specified Endpoint
 * that generates at most one Connection Request that is
 * delivered to the specified Event Dispatcher in a notification
 * event
 *
 * Input:
 *	ia_handle
 *	conn_qual
 *	ep_handle
 *	evd_handle
 *
 * Output:
 *	rsp_handle
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INSUFFICIENT_RESOURCES
 *	DAT_INVALID_PARAMETER
 *	DAT_INVALID_STATE
 *	DAT_CONN_QUAL_IN_USE
 */
DAT_RETURN
dapl_rsp_create(
	IN DAT_IA_HANDLE ia_handle,
	IN DAT_CONN_QUAL conn_qual,
	IN DAT_EP_HANDLE ep_handle,
	IN DAT_EVD_HANDLE evd_handle,
	OUT DAT_RSP_HANDLE *rsp_handle)
{
	DAPL_IA	*ia_ptr;
	DAPL_SP	*sp_ptr;
	DAPL_EVD *evd_ptr;
	DAPL_EP	*ep_ptr;
	DAT_BOOLEAN sp_found;
	DAT_RETURN dat_status;

	dat_status = DAT_SUCCESS;
	ia_ptr = (DAPL_IA *)ia_handle;

	dapl_dbg_log(DAPL_DBG_TYPE_CM,
	    ">>> dapl_rsp_free conn_qual: %x EP: %p\n",
	    conn_qual, ep_handle);

	if (DAPL_BAD_HANDLE(ia_ptr, DAPL_MAGIC_IA)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_IA);
		goto bail;
	}
	if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EP);
		goto bail;
	}
	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	if (rsp_handle == NULL) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5);
		goto bail;
	}

	ep_ptr = (DAPL_EP *) ep_handle;
	if (ep_ptr->param.ep_state != DAT_EP_STATE_UNCONNECTED) {
		dat_status = DAT_ERROR(DAT_INVALID_STATE,
		    dapls_ep_state_subtype(ep_ptr));
		goto bail;
	}

	evd_ptr = (DAPL_EVD *)evd_handle;
	if (!(evd_ptr->evd_flags & DAT_EVD_CR_FLAG)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EVD_CR);
		goto bail;
	}

	sp_ptr = dapls_ia_sp_search(ia_ptr, conn_qual, DAT_FALSE);
	sp_found = DAT_TRUE;
	if (sp_ptr == NULL) {
		sp_found = DAT_FALSE;

		/* Allocate RSP */
		sp_ptr = dapls_sp_alloc(ia_ptr, DAT_FALSE);
		if (sp_ptr == NULL) {
			dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
			    DAT_RESOURCE_MEMORY);
			goto bail;
		}
	}

	/*
	 * Fill out the RSP args
	 */
	sp_ptr->ia_handle  = ia_handle;
	sp_ptr->conn_qual  = conn_qual;
	sp_ptr->evd_handle = evd_handle;
	sp_ptr->psp_flags  = 0;
	sp_ptr->ep_handle  = ep_handle;

	/*
	 * Take a reference on the EVD handle
	 */
	(void) dapl_os_atomic_inc(&((DAPL_EVD *)evd_handle)->evd_ref_count);

	/*
	 * Update the EP state indicating the provider now owns it
	 */
	ep_ptr->param.ep_state = DAT_EP_STATE_RESERVED;

	/*
	 * Set up a listener for a connection. Connections can arrive
	 * even before this call returns!
	 */
	sp_ptr->state = DAPL_SP_STATE_RSP_LISTENING;
	sp_ptr->listening = DAT_TRUE;

	if (sp_found == DAT_FALSE) {
	/* Link it onto the IA */
		dapl_ia_link_rsp(ia_ptr, sp_ptr);

		dat_status = dapls_ib_setup_conn_listener(ia_ptr, conn_qual,
		    sp_ptr);

		if (dat_status != DAT_SUCCESS) {
			/*
			 * Have a problem setting up the connection, something
			 * wrong!
			 * rsp_free will decrement the EVD refcount. Set
			 * listening to * false to avoid tearing down the
			 * conn_listener which didn't * get set up.
			 */
			sp_ptr->listening = DAT_FALSE;
			(void) dapl_rsp_free((DAT_RSP_HANDLE) sp_ptr);

			dapl_dbg_log(DAPL_DBG_TYPE_CM,
			    "--> dapl_rsp_create setup_conn_listener failed: "
			    "%x\n",
			    dat_status);

			goto bail;
		}
	}

	/*
	 * Return handle to the user
	 */
	*rsp_handle = (DAT_RSP_HANDLE)sp_ptr;

bail:
	return (dat_status);
}
Пример #26
0
/*
 * dapl_ep_free
 *
 * DAPL Requirements Version xxx, 6.5.3
 *
 * Destroy an instance of the Endpoint
 *
 * Input:
 *	ep_handle
 *
 * Output:
 *	none
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_PARAMETER
 *	DAT_INVALID_STATE
 */
DAT_RETURN
dapl_ep_free(
	IN DAT_EP_HANDLE ep_handle)
{
	DAPL_EP	*ep_ptr;
	DAPL_IA	*ia_ptr;
	DAT_EP_PARAM *param;
	DAT_RETURN dat_status = DAT_SUCCESS;

	dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_ep_free (%p)\n", ep_handle);

	ep_ptr = (DAPL_EP *) ep_handle;
	param = &ep_ptr->param;

	/*
	 * Verify parameter & state
	 */
	if (DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) &&
	    !(ep_ptr->header.magic == DAPL_MAGIC_EP_EXIT &&
	    ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE,
		    DAT_INVALID_HANDLE_EP);
		goto bail;
	}

	if (ep_ptr->param.ep_state == DAT_EP_STATE_RESERVED ||
	    ep_ptr->param.ep_state == DAT_EP_STATE_PASSIVE_CONNECTION_PENDING ||
	    ep_ptr->param.ep_state ==
	    DAT_EP_STATE_TENTATIVE_CONNECTION_PENDING) {
		dapl_dbg_log(DAPL_DBG_TYPE_WARN,
		    "--> dapl_ep_free: invalid state: %x, ep %p\n",
		    ep_ptr->param.ep_state, ep_ptr);
		dat_status = DAT_ERROR(DAT_INVALID_STATE,
		    dapls_ep_state_subtype(ep_ptr));
		goto bail;
	}

	ia_ptr = ep_ptr->header.owner_ia;

	/*
	 * If we are connected, issue a disconnect. If we are in the
	 * disconnect_pending state, disconnect with the ABRUPT flag
	 * set.
	 */

	/*
	 * Do verification of parameters and the state change atomically.
	 */
	dapl_os_lock(&ep_ptr->header.lock);

	if (ep_ptr->param.ep_state == DAT_EP_STATE_CONNECTED ||
	    ep_ptr->param.ep_state == DAT_EP_STATE_ACTIVE_CONNECTION_PENDING ||
	    ep_ptr->param.ep_state == DAT_EP_STATE_COMPLETION_PENDING ||
	    ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) {
		/*
		 * Issue the disconnect and return. The DISCONNECT callback
		 * will invoke this routine and finish the job
		 */
		ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;
		dapl_os_unlock(&ep_ptr->header.lock);

		dapl_dbg_log(DAPL_DBG_TYPE_EP,
		    "--> dapl_ep_free: disconnecting EP: %x, ep %p\n",
		    ep_ptr->param.ep_state, ep_ptr);

		dat_status = dapls_ib_disconnect(ep_ptr, DAT_CLOSE_ABRUPT_FLAG);
		ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;
		ep_ptr->header.magic = DAPL_MAGIC_EP_EXIT;
	} else {
		dapl_os_unlock(&ep_ptr->header.lock);
	}

	/*
	 * Release all reference counts and unlink this structure. If we
	 * got here from a callback, don't repeat this step
	 */
	if (!(ep_ptr->header.magic == DAPL_MAGIC_EP_EXIT &&
	    ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED)) {
		/* Remove link from the IA */
		dapl_ia_unlink_ep(ia_ptr, ep_ptr);
	}

	/*
	 * If the EP is disconnected tear everything down.  Otherwise,
	 * disconnect the EP but leave the QP and basic EP structure
	 * intact; the callback code will finish the job.
	 */
	dapl_os_lock(&ep_ptr->header.lock);
	if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED ||
	    ep_ptr->param.ep_state == DAT_EP_STATE_UNCONNECTED) {
		/*
		 * Update ref counts. Note the user may have used ep_modify
		 * to set handles to NULL.
		 */
		if (param->pz_handle != NULL) {
			dapl_os_atomic_dec(&((DAPL_PZ *)
			    param->pz_handle)->pz_ref_count);
			param->pz_handle = NULL;
		}
		if (param->recv_evd_handle != NULL) {
			dapl_os_atomic_dec(&((DAPL_EVD *)
			    param->recv_evd_handle)->evd_ref_count);
			param->recv_evd_handle = NULL;
		}
		if (param->request_evd_handle != NULL) {
			dapl_os_atomic_dec(&((DAPL_EVD *)
			    param->request_evd_handle)->evd_ref_count);
			param->request_evd_handle = NULL;
		}
		if (param->connect_evd_handle != NULL) {
			dapl_os_atomic_dec(&((DAPL_EVD *)
			    param->connect_evd_handle)->evd_ref_count);
			param->connect_evd_handle = NULL;
		}

		if (param->srq_handle != NULL) {
			dapl_os_atomic_dec(&((DAPL_SRQ *)
			    param->srq_handle)->srq_ref_count);
			param->srq_handle = NULL;
		}

		dapl_dbg_log(DAPL_DBG_TYPE_EP,
		    "--> dapl_ep_free: Free EP: %x, ep %p\n",
		    ep_ptr->param.ep_state, ep_ptr);
		/*
		 * Free the QP. If the EP has never been used,
		 * the QP is invalid
		 */
		if (ep_ptr->qp_handle != IB_INVALID_HANDLE) {
			dat_status = dapls_ib_qp_free(ia_ptr, ep_ptr);
			/*
			 * This should always succeed, but report to the user if
			 * there is a problem
			 */
			if (dat_status != DAT_SUCCESS) {
				goto bail;
			}
			ep_ptr->qp_handle = IB_INVALID_HANDLE;
		}
		dapl_os_unlock(&ep_ptr->header.lock);
		/* Free the resource */
		dapl_ep_dealloc(ep_ptr);
	} else {
		dapl_os_unlock(&ep_ptr->header.lock);
	}
bail:
	return (dat_status);

}
Пример #27
0
/*
 * dapl_lmr_create
 *
 * Register a memory region with an Interface Adaptor.
 *
 * Input:
 *	ia_handle
 *	mem_type
 *	region_description
 *	length
 *	pz_handle
 *	privileges
 *
 * Output:
 *	lmr_handle
 *	lmr_context
 *	registered_length
 *	registered_address
 *
 * Returns:
 * 	DAT_SUCCESS
 * 	DAT_INSUFFICIENT_RESOURCES
 * 	DAT_INVALID_PARAMETER
 * 	DAT_INVALID_HANDLE
 * 	DAT_INVALID_STATE
 * 	DAT_MODEL_NOT_SUPPORTED
 *
 */
DAT_RETURN DAT_API
dapl_lmr_create(IN DAT_IA_HANDLE ia_handle,
		IN DAT_MEM_TYPE mem_type,
		IN DAT_REGION_DESCRIPTION region_description,
		IN DAT_VLEN length,
		IN DAT_PZ_HANDLE pz_handle,
		IN DAT_MEM_PRIV_FLAGS privileges,
		IN DAT_VA_TYPE va_type,
		OUT DAT_LMR_HANDLE * lmr_handle,
		OUT DAT_LMR_CONTEXT * lmr_context,
		OUT DAT_RMR_CONTEXT * rmr_context,
		OUT DAT_VLEN * registered_length,
		OUT DAT_VADDR * registered_address)
{
	DAPL_IA *ia;
	DAPL_PZ *pz;
	DAT_RETURN dat_status;

	if (DAPL_BAD_HANDLE(ia_handle, DAPL_MAGIC_IA)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA);
		goto bail;
	}
	if (DAPL_BAD_HANDLE(pz_handle, DAPL_MAGIC_PZ)) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_PZ);
		goto bail;
	}
	if (NULL == lmr_handle) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG7);
		goto bail;
	}

	ia = (DAPL_IA *) ia_handle;
	pz = (DAPL_PZ *) pz_handle;

	DAPL_CNTR(ia, DCNT_IA_LMR_CREATE);

	switch (mem_type) {
	case DAT_MEM_TYPE_VIRTUAL:
		{
			dat_status =
			    dapli_lmr_create_virtual(ia,
						     region_description.for_va,
						     length, pz, privileges,
						     va_type, lmr_handle,
						     lmr_context, rmr_context,
						     registered_length,
						     registered_address);
			break;
		}
	case DAT_MEM_TYPE_LMR:
		{
			DAPL_LMR *lmr;

			if (DAPL_BAD_HANDLE
			    (region_description.for_lmr_handle,
			     DAPL_MAGIC_LMR)) {
				dat_status =
				    DAT_ERROR(DAT_INVALID_HANDLE,
					      DAT_INVALID_HANDLE_LMR);
				goto bail;
			}

			lmr = (DAPL_LMR *) region_description.for_lmr_handle;

			dat_status =
			    dapli_lmr_create_lmr(ia, lmr, pz, privileges,
						 va_type, lmr_handle,
						 lmr_context, rmr_context,
						 registered_length,
						 registered_address);
			break;
		}
	case DAT_MEM_TYPE_SHARED_VIRTUAL:
		{
#if (VN_MEM_SHARED_VIRTUAL_SUPPORT > 0)
			dat_status =
			    dapli_lmr_create_shared(ia, region_description,
						    length, pz, privileges,
						    va_type, lmr_handle,
						    lmr_context, rmr_context,
						    registered_length,
						    registered_address);
#else
			dat_status =
			    DAT_ERROR(DAT_NOT_IMPLEMENTED, DAT_NO_SUBTYPE);
#endif
			break;
		}
	default:
		{
			dat_status =
			    DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
			break;
		}
	}

      bail:
	return dat_status;
}
Пример #28
0
/*
 * dapl_cno_wait
 *
 * DAPL Requirements Version xxx, 6.3.2.3
 *
 * Wait for a consumer notification event
 *
 * Input:
 *	cno_handle
 *	timeout
 *	evd_handle
 *
 * Output:
 *	evd_handle
 *
 * Returns:
 *	DAT_SUCCESS
 *	DAT_INVALID_HANDLE
 *	DAT_QUEUE_EMPTY
 *	DAT_INVALID_PARAMETER
 */
DAT_RETURN DAT_API dapl_cno_wait(IN DAT_CNO_HANDLE cno_handle,	/* cno_handle */
				 IN DAT_TIMEOUT timeout,	/* agent */
				 OUT DAT_EVD_HANDLE * evd_handle)
{				/* ia_handle */
	DAPL_CNO *cno_ptr;
	DAT_RETURN dat_status;

	if (DAPL_BAD_HANDLE(cno_handle, DAPL_MAGIC_CNO)) {
		dat_status = DAT_INVALID_HANDLE | DAT_INVALID_HANDLE_CNO;
		goto bail;
	}

	dat_status = DAT_SUCCESS;

	cno_ptr = (DAPL_CNO *) cno_handle;

	if (cno_ptr->cno_state == DAPL_CNO_STATE_DEAD) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_CNO_DEAD);
		goto bail;
	}

	dapl_os_lock(&cno_ptr->header.lock);
	if (cno_ptr->cno_state == DAPL_CNO_STATE_TRIGGERED) {
		cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED;
		*evd_handle = cno_ptr->cno_evd_triggered;
		cno_ptr->cno_evd_triggered = NULL;
		dapl_os_unlock(&cno_ptr->header.lock);
		goto bail;
	}

	while (cno_ptr->cno_state == DAPL_CNO_STATE_UNTRIGGERED
	       && DAT_GET_TYPE(dat_status) != DAT_TIMEOUT_EXPIRED) {
		cno_ptr->cno_waiters++;
		dapl_os_unlock(&cno_ptr->header.lock);
		dat_status = dapl_os_wait_object_wait(&cno_ptr->cno_wait_object,
						      timeout);
		dapl_os_lock(&cno_ptr->header.lock);
		cno_ptr->cno_waiters--;
	}

	if (cno_ptr->cno_state == DAPL_CNO_STATE_DEAD) {
		dat_status =
		    DAT_ERROR(DAT_INVALID_STATE, DAT_INVALID_STATE_CNO_DEAD);
	} else if (dat_status == DAT_SUCCESS) {
		/*
		 * After the first triggering, this will be a valid handle.
		 * If we're racing with wakeups of other CNO waiters,
		 * that's ok.
		 */
		dapl_os_assert(cno_ptr->cno_state == DAPL_CNO_STATE_TRIGGERED);
		cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED;
		*evd_handle = cno_ptr->cno_evd_triggered;
		cno_ptr->cno_evd_triggered = NULL;
	} else if (DAT_GET_TYPE(dat_status) == DAT_TIMEOUT_EXPIRED) {
		cno_ptr->cno_state = DAPL_CNO_STATE_UNTRIGGERED;
		*evd_handle = NULL;
		dat_status = DAT_QUEUE_EMPTY;
	} else {
		/*
		 * The only other reason we could have made it out of
		 * the loop is an interrupted system call.
		 */
		dapl_os_assert(DAT_GET_TYPE(dat_status) ==
			       DAT_INTERRUPTED_CALL);
	}
	dapl_os_unlock(&cno_ptr->header.lock);

      bail:
	return dat_status;
}
Пример #29
0
DAT_RETURN
dapli_post_ext(IN DAT_EP_HANDLE ep_handle,
	       IN DAT_UINT64 cmp_add,
	       IN DAT_UINT64 swap,
	       IN DAT_UINT32 immed_data,
	       IN DAT_COUNT segments,
	       IN DAT_LMR_TRIPLET * local_iov,
	       IN DAT_DTO_COOKIE user_cookie,
	       IN const DAT_RMR_TRIPLET * remote_iov,
	       IN int op_type,
	       IN DAT_COMPLETION_FLAGS flags, IN DAT_IB_ADDR_HANDLE * ah)
{
	DAPL_EP *ep_ptr;
	ib_qp_handle_t qp_ptr;
	DAPL_COOKIE *cookie = NULL;
	DAT_RETURN dat_status = DAT_SUCCESS;

	dapl_dbg_log(DAPL_DBG_TYPE_API,
		     " post_ext_op: ep %p cmp_val %d "
		     "swap_val %d cookie 0x%x, r_iov %p, flags 0x%x, ah %p\n",
		     ep_handle, (unsigned)cmp_add, (unsigned)swap,
		     (unsigned)user_cookie.as_64, remote_iov, flags, ah);

	if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP))
		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));

	ep_ptr = (DAPL_EP *) ep_handle;
	qp_ptr = ep_ptr->qp_handle;

	/*
	 * Synchronization ok since this buffer is only used for send
	 * requests, which aren't allowed to race with each other.
	 */
	dat_status = dapls_dto_cookie_alloc(&ep_ptr->req_buffer,
					    DAPL_DTO_TYPE_EXTENSION,
					    user_cookie, &cookie);
	if (dat_status != DAT_SUCCESS)
		goto bail;

	/*
	 * Take reference before posting to avoid race conditions with
	 * completions
	 */
	dapl_os_atomic_inc(&ep_ptr->req_count);

	/*
	 * Invoke provider specific routine to post DTO
	 */
	dat_status = dapls_ib_post_ext_send(ep_ptr, op_type, cookie, segments,	/* data segments */
					    local_iov, remote_iov, immed_data,	/* immed data */
					    cmp_add,	/* compare or add */
					    swap,	/* swap */
					    flags, ah);

	if (dat_status != DAT_SUCCESS) {
		dapl_os_atomic_dec(&ep_ptr->req_count);
		dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
	}

      bail:
	return dat_status;

}
Пример #30
0
DAT_RETURN DAT_API dapl_evd_resize(IN DAT_EVD_HANDLE evd_handle,
				   IN DAT_COUNT evd_qlen)
{
	DAPL_IA *ia_ptr;
	DAPL_EVD *evd_ptr;
	DAT_COUNT pend_cnt;
	DAT_RETURN dat_status;

	dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_evd_resize (%p, %d)\n",
		     evd_handle, evd_qlen);

	if (DAPL_BAD_HANDLE(evd_handle, DAPL_MAGIC_EVD)) {
		dat_status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE1);
		goto bail;
	}

	evd_ptr = (DAPL_EVD *) evd_handle;
	ia_ptr = evd_ptr->header.owner_ia;

	if (evd_qlen == evd_ptr->qlen) {
		dat_status = DAT_SUCCESS;
		goto bail;
	}

	if (evd_qlen > ia_ptr->hca_ptr->ia_attr.max_evd_qlen) {
		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
		goto bail;
	}

	dapl_os_lock(&evd_ptr->header.lock);

	/* Don't try to resize if we are actively waiting */
	if (evd_ptr->evd_state == DAPL_EVD_STATE_WAITED) {
		dapl_os_unlock(&evd_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);
		goto bail;
	}

	pend_cnt = dapls_rbuf_count(&evd_ptr->pending_event_queue);
	if (pend_cnt > evd_qlen) {
		dapl_os_unlock(&evd_ptr->header.lock);
		dat_status = DAT_ERROR(DAT_INVALID_STATE, 0);
		goto bail;
	}

	if (evd_ptr->ib_cq_handle) {

		dat_status = dapls_ib_cq_resize(evd_ptr->header.owner_ia,
						evd_ptr, &evd_qlen);
		if (dat_status != DAT_SUCCESS) {
			dapl_os_unlock(&evd_ptr->header.lock);
			goto bail;
		}
	}

	dat_status = dapls_evd_event_realloc(evd_ptr, evd_qlen);
	if (dat_status != DAT_SUCCESS) {
		dapl_os_unlock(&evd_ptr->header.lock);
		goto bail;
	}

	dapl_os_unlock(&evd_ptr->header.lock);

      bail:
	return dat_status;
}