root/opal/mca/btl/ugni/btl_ugni_get.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mca_btl_ugni_get
  2. mca_btl_ugni_callback_eager_get_progress_pending
  3. mca_btl_ugni_callback_eager_get
  4. mca_btl_ugni_start_eager_get

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2011-2017 Los Alamos National Security, LLC. All rights
   4  *                         reserved.
   5  * Copyright (c) 2011      UT-Battelle, LLC. All rights reserved.
   6  * $COPYRIGHT$
   7  *
   8  * Additional copyrights may follow
   9  *
  10  * $HEADER$
  11  */
  12 
  13 #include "btl_ugni_rdma.h"
  14 #include "btl_ugni_smsg.h"
  15 
  16 /* 
  17  * taken from osc_rdma_comm.h, ugh.
  18  */
  19 
  20 #define ALIGNMENT_MASK(x) ((x) ? (x) - 1 : 0)
  21 
  22 int mca_btl_ugni_get (mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint, void *local_address,
  23                       uint64_t remote_address, mca_btl_base_registration_handle_t *local_handle,
  24                       mca_btl_base_registration_handle_t *remote_handle, size_t size, int flags,
  25                       int order, mca_btl_base_rdma_completion_fn_t cbfunc, void *cbcontext, void *cbdata)
  26 {
  27     bool check;
  28 
  29     /* Check if the get is aligned/sized on a multiple of 4 */
  30     check = !!((remote_address | (uint64_t)(intptr_t) local_address | size) &
  31                  ALIGNMENT_MASK(mca_btl_ugni_module.super.btl_get_alignment));
  32 
  33     if (OPAL_UNLIKELY(check || size > mca_btl_ugni_module.super.btl_get_limit)) {
  34         BTL_VERBOSE(("RDMA/FMA Get not available due to size or alignment restrictions"));
  35 
  36         /* notify the caller that get is not available */
  37         return OPAL_ERR_NOT_AVAILABLE;
  38     }
  39 
  40     BTL_VERBOSE(("Using RDMA/FMA Get %lu bytes to local address %p to remote address %" PRIx64,
  41                  (unsigned long) size, local_address, remote_address));
  42 
  43     return mca_btl_ugni_post (endpoint, true, size, local_address, remote_address, local_handle,
  44                               remote_handle, order, cbfunc, cbcontext, cbdata);
  45 }
  46 
  47 /* eager get */
  48 static void mca_btl_ugni_callback_eager_get_progress_pending (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint,
  49                                                               struct mca_btl_base_descriptor_t *desc, int rc)
  50 {
  51     mca_btl_ugni_module_t *ugni_module = (mca_btl_ugni_module_t *) btl;
  52     mca_btl_ugni_base_frag_t *pending_frag, *frag = (mca_btl_ugni_base_frag_t *) desc;
  53 
  54     memset (&frag->hdr, 0, sizeof (frag->hdr));
  55 
  56     OPAL_THREAD_LOCK(&ugni_module->eager_get_pending_lock);
  57     pending_frag = (mca_btl_ugni_base_frag_t *) opal_list_remove_first (&ugni_module->eager_get_pending);
  58     OPAL_THREAD_UNLOCK(&ugni_module->eager_get_pending_lock);
  59 
  60     if (NULL != pending_frag) {
  61         /* copy the relevant data out of the pending fragment */
  62         frag->endpoint = pending_frag->endpoint;
  63 
  64         assert (frag != pending_frag);
  65 
  66         /* start the next eager get using this fragment */
  67         (void) mca_btl_ugni_start_eager_get (frag->endpoint, pending_frag->hdr.eager_ex, frag);
  68 
  69         /* return the temporary fragment */
  70         mca_btl_ugni_frag_return (pending_frag);
  71     } else {
  72         /* not needed anymore */
  73         mca_btl_ugni_frag_return (frag);
  74     }
  75 }
  76 
  77 static void mca_btl_ugni_callback_eager_get (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint,
  78                                              void *local_address, mca_btl_base_registration_handle_t *local_handle,
  79                                              void *context, void *cbdata, int status)
  80 {
  81     mca_btl_ugni_module_t *ugni_module = (mca_btl_ugni_module_t *) btl;
  82     mca_btl_ugni_base_frag_t *frag = (mca_btl_ugni_base_frag_t *) context;
  83     uint32_t len = frag->hdr.eager.send.lag & 0x00ffffff;
  84     uint8_t tag = frag->hdr.eager.send.lag >> 24;
  85     size_t payload_len = frag->hdr.eager.size;
  86     size_t hdr_len = len - payload_len;
  87     mca_btl_active_message_callback_t *reg;
  88     mca_btl_base_segment_t segs[2];
  89     mca_btl_ugni_base_frag_t tmp;
  90     int rc;
  91 
  92     BTL_VERBOSE(("eager get for rem_ctx %p complete", frag->hdr.eager.ctx))
  93 
  94     tmp.base.des_segments = segs;
  95     if (hdr_len) {
  96         tmp.base.des_segment_count = 2;
  97 
  98         segs[0].seg_addr.pval = frag->hdr.eager_ex.pml_header;
  99         segs[0].seg_len       = hdr_len;
 100         segs[1].seg_addr.pval = local_address;
 101         segs[1].seg_len       = payload_len;
 102     } else {
 103         tmp.base.des_segment_count = 1;
 104 
 105         segs[0].seg_addr.pval = local_address;
 106         segs[0].seg_len       = payload_len;
 107     }
 108 
 109     reg = mca_btl_base_active_message_trigger + tag;
 110     reg->cbfunc(&ugni_module->super, tag, &(tmp.base), reg->cbdata);
 111 
 112     /* fill in the response header */
 113     frag->hdr.rdma.ctx = frag->hdr.eager.ctx;
 114     frag->flags = MCA_BTL_UGNI_FRAG_RESPONSE;
 115     frag->ref_cnt = 1;
 116 
 117     frag->ref_cnt = 1;
 118 
 119     /* once complete use this fragment for a pending eager get if any exist */
 120     frag->base.des_cbfunc = mca_btl_ugni_callback_eager_get_progress_pending;
 121 
 122     /* tell the remote peer the operation is complete */
 123     rc = opal_mca_btl_ugni_smsg_send (frag, &frag->hdr.rdma, sizeof (frag->hdr.rdma),
 124                                       NULL, 0, MCA_BTL_UGNI_TAG_RDMA_COMPLETE);
 125     if (OPAL_UNLIKELY(0 > rc)) {
 126         /* queue fragment */
 127         mca_btl_ugni_wait_list_append (ugni_module, endpoint, frag);
 128     }
 129 }
 130 
 131 int mca_btl_ugni_start_eager_get (mca_btl_base_endpoint_t *endpoint,
 132                                   mca_btl_ugni_eager_ex_frag_hdr_t hdr,
 133                                   mca_btl_ugni_base_frag_t *frag)
 134 {
 135     mca_btl_ugni_module_t *ugni_module = mca_btl_ugni_ep_btl (endpoint);
 136     size_t size;
 137     int rc = OPAL_SUCCESS;
 138 
 139     BTL_VERBOSE(("starting eager get for remote ctx: %p", hdr.eager.ctx));
 140 
 141     do {
 142         if (NULL == frag) {
 143             /* try to allocate a registered buffer */
 144             frag = mca_btl_ugni_frag_alloc_eager_recv (endpoint);
 145             if (OPAL_UNLIKELY(NULL == frag)) {
 146                 /* no registered buffers available. try again later */
 147                 frag = mca_btl_ugni_frag_alloc_rdma_int (endpoint);
 148 
 149                 /* not much can be done if a small fragment can not be allocated. abort! */
 150                 assert (NULL != frag);
 151                 frag->hdr.eager_ex = hdr;
 152                 break;
 153             }
 154         }
 155 
 156         frag->flags = 0;
 157 
 158         frag->hdr.eager_ex = hdr;
 159 
 160         /* increase size to a multiple of 4 bytes (required for get on Gemini) */
 161         size = (hdr.eager.size + 3) & ~3;
 162 
 163         /* set up callback for get completion */
 164         frag->base.des_flags  = MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
 165 
 166         /* start the get */
 167         rc = mca_btl_ugni_post (endpoint, true, size, frag->base.super.ptr, hdr.eager.address,
 168                                 &frag->memory_handle, &hdr.eager.memory_handle,
 169                                 MCA_BTL_NO_ORDER, mca_btl_ugni_callback_eager_get, frag, NULL);
 170         if (OPAL_UNLIKELY(OPAL_SUCCESS == rc)) {
 171             return OPAL_SUCCESS;
 172         }
 173     } while (0);
 174 
 175     OPAL_THREAD_LOCK(&ugni_module->eager_get_pending_lock);
 176     opal_list_append (&ugni_module->eager_get_pending, (opal_list_item_t *) frag);
 177     OPAL_THREAD_UNLOCK(&ugni_module->eager_get_pending_lock);
 178 
 179     return rc;
 180 }

/* [<][>][^][v][top][bottom][index][help] */