root/opal/mca/btl/ofi/btl_ofi_frag.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_btl_ofi_base_frag_constructor
  2. mca_btl_ofi_base_frag_destructor
  3. mca_btl_ofi_alloc
  4. mca_btl_ofi_free
  5. mca_btl_ofi_send
  6. mca_btl_ofi_recv_frag
  7. mca_btl_ofi_prepare_src

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * $COPYRIGHT$
   4  * Copyright (c) 2018      Los Alamos National Security, LLC. All rights
   5  *                         reserved.
   6  * Copyright (c) 2018      Intel Inc. All rights reserved
   7  * $COPYRIGHT$
   8  *
   9  * Additional copyrights may follow
  10  *
  11  * $HEADER$
  12  */
  13 
  14 #include "btl_ofi.h"
  15 #include "btl_ofi_frag.h"
  16 #include "btl_ofi_rdma.h"
  17 #include "btl_ofi_endpoint.h"
  18 
  19 static void mca_btl_ofi_base_frag_constructor (mca_btl_ofi_base_frag_t *frag)
  20 {
  21     /* zero everything out */
  22     memset ((char *) frag + sizeof (frag->base), 0, sizeof (*frag) - sizeof (frag->base));
  23 
  24     frag->base.des_segments = frag->segments;
  25     frag->base.des_segment_count = 1;
  26 }
  27 
  28 static void mca_btl_ofi_base_frag_destructor (mca_btl_ofi_base_frag_t *frag)
  29 {
  30 
  31 }
  32 
  33 OBJ_CLASS_INSTANCE(mca_btl_ofi_base_frag_t,
  34                    mca_btl_base_descriptor_t,
  35                    mca_btl_ofi_base_frag_constructor,
  36                    mca_btl_ofi_base_frag_destructor);
  37 
  38 OBJ_CLASS_INSTANCE(mca_btl_ofi_frag_completion_t,
  39                    opal_free_list_item_t,
  40                    NULL,
  41                    NULL);
  42 
  43 mca_btl_ofi_frag_completion_t *mca_btl_ofi_frag_completion_alloc
  44                                         (mca_btl_base_module_t *btl,
  45                                          mca_btl_ofi_context_t *context,
  46                                          mca_btl_ofi_base_frag_t *frag,
  47                                          int type)
  48 {
  49     mca_btl_ofi_frag_completion_t *comp;
  50 
  51     comp = (mca_btl_ofi_frag_completion_t*) opal_free_list_get(&context->frag_comp_list);
  52     comp->base.btl = btl;
  53     comp->base.my_context = context;
  54     comp->base.my_list = &context->frag_comp_list;
  55     comp->base.type = type;
  56 
  57     comp->frag = frag;
  58     comp->comp_ctx.comp = comp;
  59 
  60     return comp;
  61 }
  62 
  63 
  64 mca_btl_base_descriptor_t *mca_btl_ofi_alloc(
  65                                 mca_btl_base_module_t *btl,
  66                                 mca_btl_base_endpoint_t *endpoint,
  67                                 uint8_t order, size_t size, uint32_t flags)
  68 {
  69     mca_btl_ofi_module_t *ofi_btl = (mca_btl_ofi_module_t*) btl;
  70     mca_btl_ofi_base_frag_t *frag = NULL;
  71     mca_btl_ofi_context_t *context = get_ofi_context(ofi_btl);
  72 
  73     frag = mca_btl_ofi_frag_alloc(ofi_btl, &context->frag_list, endpoint);
  74 
  75     if (OPAL_LIKELY(frag)) {
  76         frag->segments[0].seg_addr.pval = frag + 1;
  77         frag->segments[0].seg_len = size;
  78 
  79         frag->base.des_segment_count = 1;
  80         frag->base.des_segments = &frag->segments[0];
  81         frag->base.des_flags = flags;
  82         frag->base.order     = order;
  83         frag->hdr.len        = size;
  84     }
  85 
  86     return (mca_btl_base_descriptor_t*) frag;
  87 }
  88 
  89 int mca_btl_ofi_free (mca_btl_base_module_t *btl, mca_btl_base_descriptor_t *des)
  90 {
  91     /* return the frag to the free list. */
  92     mca_btl_ofi_frag_return ((mca_btl_ofi_base_frag_t*) des);
  93     return OPAL_SUCCESS;
  94 }
  95 
  96 int mca_btl_ofi_send (mca_btl_base_module_t *btl,
  97                       mca_btl_base_endpoint_t *endpoint,
  98                       mca_btl_base_descriptor_t *descriptor,
  99                       mca_btl_base_tag_t tag)
 100 {
 101     int rc = 0;
 102     mca_btl_ofi_context_t *context;
 103     mca_btl_ofi_module_t *ofi_btl = (mca_btl_ofi_module_t*) btl;
 104     mca_btl_ofi_endpoint_t *ofi_ep = (mca_btl_ofi_endpoint_t*) endpoint;
 105     mca_btl_ofi_base_frag_t *frag = (mca_btl_ofi_base_frag_t*) descriptor;
 106     mca_btl_ofi_frag_completion_t *comp;
 107 
 108     frag->base.des_flags |= MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
 109 
 110     /* This tag is the active message tag for the remote side */
 111     frag->hdr.tag = tag;
 112 
 113     /* create completion context */
 114     context = get_ofi_context(ofi_btl);
 115     comp = mca_btl_ofi_frag_completion_alloc(btl, context, frag,
 116                                              MCA_BTL_OFI_TYPE_SEND);
 117 
 118     /* send the frag. Note that we start sending from BTL header + payload
 119      * because we need the other side to have this header information. */
 120     rc = fi_send(context->tx_ctx,
 121                  &frag->hdr,
 122                  sizeof(mca_btl_ofi_header_t) +  frag->hdr.len,
 123                  NULL,
 124                  ofi_ep->peer_addr,
 125                  &comp->comp_ctx);
 126 
 127     if (OPAL_UNLIKELY(FI_SUCCESS != rc)) {
 128         return OPAL_ERR_OUT_OF_RESOURCE;
 129     }
 130 
 131     MCA_BTL_OFI_NUM_SEND_INC(ofi_btl);
 132     return OPAL_SUCCESS;
 133 }
 134 
 135 int mca_btl_ofi_recv_frag (mca_btl_ofi_module_t *ofi_btl,
 136                            mca_btl_base_endpoint_t *endpoint,
 137                            mca_btl_ofi_context_t *context,
 138                            mca_btl_ofi_base_frag_t *frag)
 139 {
 140     int rc;
 141     mca_btl_active_message_callback_t *reg;
 142 
 143     /* Tell PML where the payload is */
 144     frag->base.des_segments = frag->segments;
 145     frag->segments[0].seg_addr.pval = frag+1;
 146     frag->segments[0].seg_len = frag->hdr.len;
 147     frag->base.des_segment_count = 1;
 148 
 149     /* call the callback */
 150     reg = mca_btl_base_active_message_trigger + frag->hdr.tag;
 151     reg->cbfunc (&ofi_btl->super, frag->hdr.tag, &frag->base, reg->cbdata);
 152     mca_btl_ofi_frag_complete(frag, OPAL_SUCCESS);
 153 
 154     /* repost the recv */
 155     rc = mca_btl_ofi_post_recvs((mca_btl_base_module_t*) ofi_btl, context, 1);
 156     if (OPAL_SUCCESS != rc) {
 157         /* might not be that bad but let's just fail here. */
 158         BTL_ERROR(("failed reposting receive."));
 159         MCA_BTL_OFI_ABORT();
 160     }
 161 
 162     return OPAL_SUCCESS;
 163 }
 164 
 165 struct mca_btl_base_descriptor_t *mca_btl_ofi_prepare_src (
 166                                                 mca_btl_base_module_t *btl,
 167                                                 mca_btl_base_endpoint_t *endpoint,
 168                                                 opal_convertor_t *convertor,
 169                                                 uint8_t order, size_t reserve,
 170                                                 size_t *size, uint32_t flags)
 171 {
 172     struct iovec iov;
 173     size_t length;
 174     uint32_t iov_count = 1;
 175     mca_btl_ofi_base_frag_t *frag;
 176 
 177     /* allocate the frag with reserve. */
 178     frag = (mca_btl_ofi_base_frag_t*) mca_btl_ofi_alloc(btl, endpoint,
 179                                                         order, reserve, flags);
 180     if (OPAL_UNLIKELY(NULL == frag)) {
 181         return NULL;
 182     }
 183 
 184     /* pack the data after the reserve */
 185     iov.iov_len = *size;
 186     iov.iov_base = (IOVBASE_TYPE*)(((unsigned char*)(frag->segments[0].seg_addr.pval)) + reserve);
 187     opal_convertor_pack(convertor, &iov, &iov_count, &length);
 188 
 189     /* pass on frag information */
 190     frag->base.des_segments = frag->segments;
 191     frag->base.des_flags = flags;
 192     frag->base.order = MCA_BTL_NO_ORDER;
 193     frag->segments[0].seg_len += length;
 194     frag->hdr.len += length;
 195     *size = length;
 196 
 197     return &frag->base;
 198 }

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