/* * 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); }
static DAT_RETURN dapli_rmr_bind_fuse( IN DAPL_RMR *rmr, IN const DAT_LMR_TRIPLET* lmr_triplet, IN DAT_MEM_PRIV_FLAGS mem_priv, IN DAPL_EP *ep_ptr, IN DAT_RMR_COOKIE user_cookie, IN DAT_COMPLETION_FLAGS completion_flags, OUT DAT_RMR_CONTEXT *rmr_context) { DAPL_LMR *lmr; DAPL_COOKIE *cookie; DAT_RETURN dat_status; dat_status = dapls_hash_search( rmr->header.owner_ia->hca_ptr->lmr_hash_table, lmr_triplet->lmr_context, (DAPL_HASH_DATA *) &lmr); if (DAT_SUCCESS != dat_status) { dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2); goto bail; } /* * if the ep in unconnected return an error. IB requires that the * QP be connected to change a memory window binding since: * * - memory window bind operations are WQEs placed on a QP's * send queue * * - QP's only process WQEs on the send queue when the QP is in * the RTS state */ if (DAT_EP_STATE_CONNECTED != ep_ptr->param.ep_state) { dat_status = DAT_ERROR(DAT_INVALID_STATE, dapls_ep_state_subtype(ep_ptr)); goto bail; } if (DAT_FALSE == dapl_mr_bounds_check( dapl_mr_get_address(lmr->param.region_desc, lmr->param.mem_type), lmr->param.length, lmr_triplet->virtual_address, lmr_triplet->segment_length)) { dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2); goto bail; } /* If the LMR, RMR, and EP are not in the same PZ, there is an error */ if ((ep_ptr->param.pz_handle != lmr->param.pz_handle) || (ep_ptr->param.pz_handle != rmr->param.pz_handle)) { dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4); goto bail; } if (!dapl_rmr_validate_completion_flag(DAT_COMPLETION_SUPPRESS_FLAG, ep_ptr->param.ep_attr.request_completion_flags, completion_flags) || !dapl_rmr_validate_completion_flag(DAT_COMPLETION_UNSIGNALLED_FLAG, ep_ptr->param.ep_attr.request_completion_flags, completion_flags) || !dapl_rmr_validate_completion_flag( DAT_COMPLETION_BARRIER_FENCE_FLAG, ep_ptr->param.ep_attr.request_completion_flags, completion_flags)) { dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4); goto bail; } dat_status = dapls_rmr_cookie_alloc(&ep_ptr->req_buffer, rmr, user_cookie, &cookie); if (DAT_SUCCESS != dat_status) { goto bail; } dat_status = dapls_ib_mw_bind(rmr, lmr_triplet->lmr_context, ep_ptr, cookie, lmr_triplet->virtual_address, lmr_triplet->segment_length, mem_priv, completion_flags); if (DAT_SUCCESS != dat_status) { dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie); goto bail; } (void) dapl_os_atomic_inc(&lmr->lmr_ref_count); /* if the RMR was previously bound */ if (NULL != rmr->lmr) { (void) dapl_os_atomic_dec(&rmr->lmr->lmr_ref_count); } rmr->param.mem_priv = mem_priv; rmr->param.lmr_triplet = *lmr_triplet; rmr->ep = ep_ptr; rmr->lmr = lmr; dapl_os_atomic_inc(&ep_ptr->req_count); if (NULL != rmr_context) { *rmr_context = rmr->param.rmr_context; } bail: return (dat_status); }
/* * 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); }
/* * 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; }
static DAT_RETURN dapli_rmr_bind_unfuse( IN DAPL_RMR *rmr, IN const DAT_LMR_TRIPLET *lmr_triplet, IN DAPL_EP *ep_ptr, IN DAT_RMR_COOKIE user_cookie, IN DAT_COMPLETION_FLAGS completion_flags) { DAPL_COOKIE *cookie; DAT_RETURN dat_status; dat_status = DAT_SUCCESS; /* * if the ep in unconnected return an error. IB requires that the * QP be connected to change a memory window binding since: * * - memory window bind operations are WQEs placed on a QP's * send queue * * - QP's only process WQEs on the send queue when the QP is in * the RTS state */ if (DAT_EP_STATE_CONNECTED != ep_ptr->param.ep_state) { dat_status = DAT_ERROR(DAT_INVALID_STATE, dapls_ep_state_subtype(ep_ptr)); goto bail1; } /* If the RMR and EP are not in the same PZ, there is an error */ if (ep_ptr->param.pz_handle != rmr->param.pz_handle) { dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2); goto bail1; } if (!dapl_rmr_validate_completion_flag(DAT_COMPLETION_SUPPRESS_FLAG, ep_ptr->param.ep_attr.request_completion_flags, completion_flags) || !dapl_rmr_validate_completion_flag(DAT_COMPLETION_UNSIGNALLED_FLAG, ep_ptr->param.ep_attr.request_completion_flags, completion_flags) || !dapl_rmr_validate_completion_flag( DAT_COMPLETION_BARRIER_FENCE_FLAG, ep_ptr->param.ep_attr.request_completion_flags, completion_flags)) { dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2); goto bail1; } dat_status = dapls_rmr_cookie_alloc(&ep_ptr->req_buffer, rmr, user_cookie, &cookie); if (DAT_SUCCESS != dat_status) { goto bail1; } dat_status = dapls_ib_mw_unbind(rmr, lmr_triplet->lmr_context, ep_ptr, cookie, completion_flags); if (DAT_SUCCESS != dat_status) { dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie); goto bail1; } /* if the RMR was previously bound */ if (NULL != rmr->lmr) { (void) dapl_os_atomic_dec(&rmr->lmr->lmr_ref_count); } rmr->param.mem_priv = DAT_MEM_PRIV_NONE_FLAG; rmr->param.lmr_triplet.lmr_context = 0; rmr->param.lmr_triplet.virtual_address = 0; rmr->param.lmr_triplet.segment_length = 0; rmr->ep = ep_ptr; rmr->lmr = NULL; dapl_os_atomic_inc(&ep_ptr->req_count); bail1: return (dat_status); }
DAT_RETURN dapli_lmr_create_virtual(IN DAPL_IA * ia, IN DAT_PVOID virt_addr, IN DAT_VLEN length, IN DAPL_PZ * pz, 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_LMR *lmr; DAT_REGION_DESCRIPTION reg_desc; DAT_RETURN dat_status; reg_desc.for_va = virt_addr; dat_status = DAT_SUCCESS; dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_lmr_create (ia=%p,pz=%p)\n", ia, pz); lmr = dapl_lmr_alloc(ia, DAT_MEM_TYPE_VIRTUAL, reg_desc, length, (DAT_PZ_HANDLE) pz, privileges); if (NULL == lmr) { dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); goto bail; } dat_status = dapls_ib_mr_register(ia, lmr, virt_addr, length, privileges, va_type); #ifdef DAPL_COUNTERS dapl_os_memchk(g_dapl_dbg_mem, "create_mr"); #endif if (DAT_SUCCESS != dat_status) { dapl_lmr_dealloc(lmr); goto bail; } dapl_os_atomic_inc(&pz->pz_ref_count); *lmr_handle = (DAT_LMR_HANDLE) lmr; if (NULL != lmr_context) { *lmr_context = lmr->param.lmr_context; } if (NULL != rmr_context) { *rmr_context = lmr->param.rmr_context; } if (NULL != registered_length) { *registered_length = lmr->param.registered_size; } if (NULL != registered_address) { *registered_address = lmr->param.registered_address; } bail: return dat_status; }
/* * 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; }
DAT_RETURN dapli_lmr_create_shared(IN DAPL_IA * ia, IN DAT_REGION_DESCRIPTION reg_desc, IN DAT_VLEN length, IN DAPL_PZ * pz, 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_LMR *lmr; DAT_RETURN dat_status; dat_status = DAT_SUCCESS; dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_lmr_create_shared_virtual (ia=%p len=%x pz=%p priv=%x)\n", ia, length, pz, privileges); lmr = dapl_lmr_alloc(ia, DAT_MEM_TYPE_LMR, reg_desc, length, /* length is meaningless */ (DAT_PZ_HANDLE) pz, privileges); if (NULL == lmr) { dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); goto bail; } /* * Added for the shared memory support - - - * Save the region description. We need to copy the shared * memory id because the region_desc only contains a pointer * to it. */ dapl_os_memcpy(&lmr->shmid, reg_desc.for_shared_memory.shared_memory_id, sizeof(lmr->shmid)); lmr->param.region_desc = reg_desc; lmr->param.length = length; lmr->param.mem_type = DAT_MEM_TYPE_SHARED_VIRTUAL; lmr->param.region_desc.for_shared_memory.shared_memory_id = &lmr->shmid; dat_status = dapls_ib_mr_register_shared(ia, lmr, privileges, va_type); if (dat_status != DAT_SUCCESS) { dapl_lmr_dealloc(lmr); dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY_REGION); goto bail; } dapl_os_atomic_inc(&pz->pz_ref_count); *lmr_handle = (DAT_LMR_HANDLE) lmr; if (NULL != lmr_context) { *lmr_context = (DAT_LMR_CONTEXT) lmr->param.lmr_context; } if (NULL != rmr_context) { *rmr_context = (DAT_LMR_CONTEXT) lmr->param.rmr_context; } if (NULL != registered_length) { *registered_length = lmr->param.length; } if (NULL != registered_address) { *registered_address = (DAT_VADDR) (uintptr_t) lmr->param.region_desc.for_shared_memory.virtual_address; } bail: return dat_status; }
DAT_RETURN dapli_lmr_create_lmr(IN DAPL_IA * ia, IN DAPL_LMR * original_lmr, IN DAPL_PZ * pz, 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_LMR *lmr; DAT_REGION_DESCRIPTION reg_desc; DAT_RETURN dat_status; dapl_dbg_log(DAPL_DBG_TYPE_API, "dapl_lmr_create_lmr (%p, %p, %p, %x, %x, %p, %p, %p, %p)\n", ia, original_lmr, pz, privileges, va_type, lmr_handle, lmr_context, registered_length, registered_address); reg_desc.for_lmr_handle = (DAT_LMR_HANDLE) original_lmr; lmr = dapl_lmr_alloc(ia, DAT_MEM_TYPE_LMR, reg_desc, original_lmr->param.length, (DAT_PZ_HANDLE) pz, privileges); if (NULL == lmr) { dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); goto bail; } dat_status = dapls_ib_mr_register_shared(ia, lmr, privileges, va_type); if (DAT_SUCCESS != dat_status) { dapl_lmr_dealloc(lmr); goto bail; } dapl_os_atomic_inc(&pz->pz_ref_count); *lmr_handle = (DAT_LMR_HANDLE) lmr; if (NULL != lmr_context) { *lmr_context = lmr->param.lmr_context; } if (NULL != rmr_context) { *rmr_context = lmr->param.rmr_context; } if (NULL != registered_length) { *registered_length = lmr->param.registered_size; } if (NULL != registered_address) { *registered_address = lmr->param.registered_address; } bail: return dat_status; }
/* * 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; }
/* * dapli_open_query_ext * * * Direct link to provider for quick provider query without full IA device open * * Input: * provider name * ia_attr * provider_attr * * Output: * ia_attr * provider_attr * * 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 dapli_open_query_ext(IN const DAT_NAME_PTR name, OUT DAT_IA_HANDLE * ia_handle_ptr, IN DAT_IA_ATTR_MASK ia_mask, OUT DAT_IA_ATTR * ia_attr, IN DAT_PROVIDER_ATTR_MASK pr_mask, OUT DAT_PROVIDER_ATTR * pr_attr) { DAT_RETURN dat_status = DAT_SUCCESS; DAT_PROVIDER *provider; DAPL_HCA *hca_ptr = NULL; DAT_IA_HANDLE ia_ptr = NULL; dapl_log(DAPL_DBG_TYPE_EXTENSION, "dapli_open_query_ext (%s, 0x%llx, %p, 0x%x, %p)\n", name, ia_mask, ia_attr, pr_mask, pr_attr); 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_attr == NULL) && (pr_attr == NULL)) { return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5); } /* 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 open_query calls */ if (dapl_os_get_env_val("DAPL_DBG_TYPE", 0)) g_dapl_dbg_type = dapl_os_get_env_val("DAPL_DBG_TYPE", 0); /* * 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) { /* open in query mode */ dat_status = dapls_ib_open_hca(hca_ptr->name, hca_ptr, DAPL_OPEN_QUERY); 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; } } /* 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 = (DAT_IA_HANDLE) dapl_ia_alloc(provider, hca_ptr); if (!ia_ptr) { dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); goto cleanup; } dat_status = dapl_ia_query(ia_ptr, NULL, ia_mask, ia_attr, pr_mask, pr_attr); if (dat_status != DAT_SUCCESS) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, "dapls_ib_query_hca failed %x\n", dat_status); goto cleanup; } *ia_handle_ptr = ia_ptr; return DAT_SUCCESS; cleanup: /* close device and release HCA reference */ if (ia_ptr) { dapl_ia_close(ia_ptr, DAT_CLOSE_ABRUPT_FLAG); } else { dapl_os_lock(&hca_ptr->lock); dapls_ib_close_hca(hca_ptr); hca_ptr->ib_hca_handle = IB_INVALID_HANDLE; dapl_os_atomic_dec(&hca_ptr->handle_ref_count); dapl_os_unlock(&hca_ptr->lock); } bail: return dat_status; }
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; }