/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2014-2016 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "btl_openib.h" #include "btl_openib_endpoint.h" #include "btl_openib_proc.h" #include "btl_openib_xrc.h" #if HAVE_DECL_IBV_ATOMIC_HCA static int mca_btl_openib_atomic_internal (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint, void *local_address, uint64_t remote_address, mca_btl_base_registration_handle_t *local_handle, mca_btl_base_registration_handle_t *remote_handle, enum ibv_wr_opcode opcode, int64_t operand, int64_t operand2, int flags, int order, mca_btl_base_rdma_completion_fn_t cbfunc, void *cbcontext, void *cbdata) { mca_btl_openib_get_frag_t* frag = NULL; int qp = order; int32_t rkey; int rc; frag = to_get_frag(alloc_recv_user_frag()); if (OPAL_UNLIKELY(NULL == frag)) { return OPAL_ERR_OUT_OF_RESOURCE; } if (MCA_BTL_NO_ORDER == qp) { qp = mca_btl_openib_component.rdma_qp; } /* set base descriptor flags */ to_base_frag(frag)->base.order = qp; /* free this descriptor when the operation is complete */ to_base_frag(frag)->base.des_flags = MCA_BTL_DES_FLAGS_BTL_OWNERSHIP; /* set up scatter-gather entry */ to_com_frag(frag)->sg_entry.length = 8; to_com_frag(frag)->sg_entry.lkey = local_handle->lkey; to_com_frag(frag)->sg_entry.addr = (uint64_t)(uintptr_t) local_address; to_com_frag(frag)->endpoint = endpoint; /* set up rdma callback */ frag->cb.func = cbfunc; frag->cb.context = cbcontext; frag->cb.data = cbdata; frag->cb.local_handle = local_handle; /* set up descriptor */ frag->sr_desc.wr.atomic.remote_addr = remote_address; frag->sr_desc.opcode = opcode; frag->sr_desc.wr.atomic.compare_add = operand; frag->sr_desc.wr.atomic.swap = operand2; rkey = remote_handle->rkey; #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT if((endpoint->endpoint_proc->proc_opal->proc_arch & OPAL_ARCH_ISBIGENDIAN) != (opal_proc_local_get()->proc_arch & OPAL_ARCH_ISBIGENDIAN)) { rkey = opal_swap_bytes4 (rkey); } #endif frag->sr_desc.wr.atomic.rkey = rkey; /* NTH: the SRQ# is set in mca_btl_get_internal */ if (endpoint->endpoint_state != MCA_BTL_IB_CONNECTED) { OPAL_THREAD_LOCK(&endpoint->endpoint_lock); rc = check_endpoint_state(endpoint, &to_base_frag(frag)->base, &endpoint->pending_get_frags); OPAL_THREAD_UNLOCK(&endpoint->endpoint_lock); if (OPAL_ERR_RESOURCE_BUSY == rc) { return OPAL_SUCCESS; } if (OPAL_SUCCESS != rc) { MCA_BTL_IB_FRAG_RETURN (frag); return rc; } } rc = mca_btl_openib_get_internal (btl, endpoint, frag); if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) { if (OPAL_LIKELY(OPAL_ERR_OUT_OF_RESOURCE == rc)) { rc = OPAL_SUCCESS; OPAL_THREAD_SCOPED_LOCK(&endpoint->endpoint_lock, opal_list_append(&endpoint->pending_get_frags, (opal_list_item_t*)frag)); } else { MCA_BTL_IB_FRAG_RETURN (frag); } } return rc; } int mca_btl_openib_atomic_fop (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint, void *local_address, uint64_t remote_address, struct mca_btl_base_registration_handle_t *local_handle, struct mca_btl_base_registration_handle_t *remote_handle, mca_btl_base_atomic_op_t op, uint64_t operand, int flags, int order, mca_btl_base_rdma_completion_fn_t cbfunc, void *cbcontext, void *cbdata) { if (OPAL_UNLIKELY(MCA_BTL_ATOMIC_ADD != op || (MCA_BTL_ATOMIC_FLAG_32BIT & flags))) { return OPAL_ERR_NOT_SUPPORTED; } return mca_btl_openib_atomic_internal (btl, endpoint, local_address, remote_address, local_handle, remote_handle, IBV_WR_ATOMIC_FETCH_AND_ADD, operand, 0, flags, order, cbfunc, cbcontext, cbdata); } int mca_btl_openib_atomic_cswap (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint, void *local_address, uint64_t remote_address, struct mca_btl_base_registration_handle_t *local_handle, struct mca_btl_base_registration_handle_t *remote_handle, uint64_t compare, uint64_t value, int flags, int order, mca_btl_base_rdma_completion_fn_t cbfunc, void *cbcontext, void *cbdata) { if (OPAL_UNLIKELY(MCA_BTL_ATOMIC_FLAG_32BIT & flags)) { return OPAL_ERR_NOT_SUPPORTED; } return mca_btl_openib_atomic_internal (btl, endpoint, local_address, remote_address, local_handle, remote_handle, IBV_WR_ATOMIC_CMP_AND_SWP, compare, value, flags, order, cbfunc, cbcontext, cbdata); } #endif