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); }
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); }
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; }