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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_btl_ugni_wait_list_append
  2. mca_btl_ugni_send
  3. mca_btl_ugni_sendi
  4. mca_btl_ugni_progress_send_wait_list

   1 /* -*- Mode: C; c-basic-offset:3 ; 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 (c) 2014      Research Organization for Information Science
   7  *                         and Technology (RIST). All rights reserved.
   8  * Copyright (c) 2017      Intel, Inc.  All rights reserved.
   9  * $COPYRIGHT$
  10  *
  11  * Additional copyrights may follow
  12  *
  13  * $HEADER$
  14  */
  15 
  16 #include "btl_ugni.h"
  17 #include "btl_ugni_frag.h"
  18 #include "btl_ugni_smsg.h"
  19 #include "btl_ugni_prepare.h"
  20 
  21 void mca_btl_ugni_wait_list_append (mca_btl_ugni_module_t *ugni_module, mca_btl_base_endpoint_t *endpoint,
  22                                     mca_btl_ugni_base_frag_t *frag)
  23 {
  24     BTL_VERBOSE(("wait-listing fragment %p to %s. endpoint state %d\n", (void*)frag, OPAL_NAME_PRINT(endpoint->peer_proc->proc_name), endpoint->state));
  25 
  26     frag->base.des_flags |= MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
  27 
  28     /* queue up request */
  29     OPAL_THREAD_LOCK(&endpoint->lock);
  30 
  31     opal_list_append (&endpoint->frag_wait_list, (opal_list_item_t *) frag);
  32 
  33     OPAL_THREAD_UNLOCK(&endpoint->lock);
  34 
  35     if (false == endpoint->wait_listed && MCA_BTL_UGNI_EP_STATE_CONNECTED == endpoint->state) {
  36         OPAL_THREAD_LOCK(&ugni_module->ep_wait_list_lock);
  37         if (false == endpoint->wait_listed) {
  38             opal_list_append (&ugni_module->ep_wait_list, &endpoint->super);
  39             endpoint->wait_listed = true;
  40         }
  41         OPAL_THREAD_UNLOCK(&ugni_module->ep_wait_list_lock);
  42     }
  43 }
  44 
  45 int mca_btl_ugni_send (struct mca_btl_base_module_t *btl,
  46                        struct mca_btl_base_endpoint_t *endpoint,
  47                        struct mca_btl_base_descriptor_t *descriptor,
  48                        mca_btl_base_tag_t tag)
  49 {
  50     mca_btl_ugni_base_frag_t *frag = (mca_btl_ugni_base_frag_t *) descriptor;
  51     size_t size = frag->segments[0].seg_len + frag->segments[1].seg_len;
  52     mca_btl_ugni_module_t *ugni_module = (mca_btl_ugni_module_t *) btl;
  53     int rc;
  54 
  55     /* tag and len are at the same location in eager and smsg frag hdrs */
  56     frag->hdr.send.lag = (tag << 24) | size;
  57 
  58     BTL_VERBOSE(("btl/ugni sending descriptor %p from %d -> %d. length = %" PRIu64, (void *)descriptor,
  59                  OPAL_PROC_MY_NAME.vpid, endpoint->peer_proc->proc_name.vpid, size));
  60 
  61     rc = mca_btl_ugni_check_endpoint_state (endpoint);
  62     if (OPAL_UNLIKELY(OPAL_SUCCESS != rc || opal_list_get_size (&endpoint->frag_wait_list))) {
  63         mca_btl_ugni_wait_list_append (ugni_module, endpoint, frag);
  64         return OPAL_SUCCESS;
  65     }
  66 
  67     /* add a reference to prevent the fragment from being returned until after the
  68      * completion flag is checked. */
  69     ++frag->ref_cnt;
  70     frag->flags &= ~MCA_BTL_UGNI_FRAG_COMPLETE;
  71 
  72     rc = mca_btl_ugni_send_frag (endpoint, frag);
  73     if (OPAL_LIKELY(mca_btl_ugni_frag_check_complete (frag))) {
  74         /* fast path: remote side has received the frag */
  75         (void) mca_btl_ugni_frag_del_ref (frag, OPAL_SUCCESS);
  76 
  77         return 1;
  78     }
  79 
  80     if ((OPAL_SUCCESS == rc) && (frag->flags & MCA_BTL_UGNI_FRAG_BUFFERED) && (frag->flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP)) {
  81         /* fast(ish) path: btl owned buffered frag. report send as complete */
  82         bool call_callback = !!(frag->flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK);
  83         frag->flags &= ~MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
  84 
  85         if (call_callback) {
  86             frag->base.des_cbfunc(&ugni_module->super, frag->endpoint, &frag->base, rc);
  87         }
  88 
  89         (void) mca_btl_ugni_frag_del_ref (frag, OPAL_SUCCESS);
  90 
  91         return 1;
  92     }
  93 
  94     /* slow(ish) path: remote side hasn't received the frag. call the frag's callback when
  95        we get the local smsg/msgq or remote rdma completion */
  96     frag->base.des_flags |= MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
  97 
  98     mca_btl_ugni_frag_del_ref (frag, OPAL_SUCCESS);
  99 
 100     if (OPAL_UNLIKELY(OPAL_ERR_OUT_OF_RESOURCE == rc)) {
 101         /* queue up request */
 102         mca_btl_ugni_wait_list_append (ugni_module, endpoint, frag);
 103         rc = OPAL_SUCCESS;
 104     }
 105 
 106     return rc;
 107 }
 108 
 109 int mca_btl_ugni_sendi (struct mca_btl_base_module_t *btl,
 110                         struct mca_btl_base_endpoint_t *endpoint,
 111                         struct opal_convertor_t *convertor,
 112                         void *header, size_t header_size,
 113                         size_t payload_size, uint8_t order,
 114                         uint32_t flags, mca_btl_base_tag_t tag,
 115                         mca_btl_base_descriptor_t **descriptor)
 116 {
 117     size_t total_size = header_size + payload_size;
 118     mca_btl_ugni_base_frag_t *frag = NULL;
 119     size_t packed_size = payload_size;
 120     int rc;
 121 
 122     if (OPAL_UNLIKELY(opal_list_get_size (&endpoint->frag_wait_list))) {
 123         if (NULL != descriptor) {
 124             *descriptor = NULL;
 125         }
 126         return OPAL_ERR_OUT_OF_RESOURCE;
 127     }
 128 
 129     do {
 130         BTL_VERBOSE(("btl/ugni isend sending fragment from %d -> %d. length = %" PRIu64
 131                      " endoint state %d", OPAL_PROC_MY_NAME.vpid, endpoint->peer_proc->proc_name.vpid,
 132                      payload_size + header_size, endpoint->state));
 133 
 134         flags |= MCA_BTL_DES_FLAGS_BTL_OWNERSHIP;
 135 
 136         if (0 == payload_size) {
 137             frag = (mca_btl_ugni_base_frag_t *) mca_btl_ugni_prepare_src_send_nodata (btl, endpoint, order, header_size,
 138                                                                                       flags);
 139         } else {
 140             frag = (mca_btl_ugni_base_frag_t *) mca_btl_ugni_prepare_src_send_buffered (btl, endpoint, convertor, order,
 141                                                                                         header_size, &packed_size, flags);
 142         }
 143 
 144         assert (packed_size == payload_size);
 145         if (OPAL_UNLIKELY(NULL == frag || OPAL_SUCCESS != mca_btl_ugni_check_endpoint_state (endpoint))) {
 146             break;
 147         }
 148 
 149         frag->hdr.send.lag = (tag << 24) | total_size;
 150         memcpy (frag->segments[0].seg_addr.pval, header, header_size);
 151 
 152         rc = mca_btl_ugni_send_frag (endpoint, frag);
 153         if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
 154             break;
 155         }
 156 
 157         return OPAL_SUCCESS;
 158     } while (0);
 159 
 160     if (NULL != descriptor) {
 161         *descriptor = &frag->base;
 162     }
 163 
 164     return OPAL_ERR_OUT_OF_RESOURCE;
 165 }
 166 
 167 int mca_btl_ugni_progress_send_wait_list (mca_btl_base_endpoint_t *endpoint)
 168 {
 169     mca_btl_ugni_base_frag_t *frag=NULL;
 170     int rc;
 171 
 172     do {
 173         OPAL_THREAD_LOCK(&endpoint->lock);
 174         frag = (mca_btl_ugni_base_frag_t *) opal_list_remove_first (&endpoint->frag_wait_list);
 175         OPAL_THREAD_UNLOCK(&endpoint->lock);
 176         if (NULL == frag) {
 177             break;
 178         }
 179         if (OPAL_LIKELY(!(frag->flags & MCA_BTL_UGNI_FRAG_RESPONSE))) {
 180             rc = mca_btl_ugni_send_frag (endpoint, frag);
 181         } else {
 182             rc = opal_mca_btl_ugni_smsg_send (frag, &frag->hdr.rdma, sizeof (frag->hdr.rdma),
 183                                               NULL, 0, MCA_BTL_UGNI_TAG_RDMA_COMPLETE);
 184         }
 185 
 186         if (OPAL_UNLIKELY(OPAL_SUCCESS > rc)) {
 187             if (OPAL_LIKELY(OPAL_ERR_OUT_OF_RESOURCE == rc)) {
 188                 OPAL_THREAD_LOCK(&endpoint->lock);
 189                 opal_list_prepend (&endpoint->frag_wait_list, (opal_list_item_t *) frag);
 190                 OPAL_THREAD_UNLOCK(&endpoint->lock);
 191             } else {
 192                 mca_btl_ugni_frag_complete (frag, rc);
 193             }
 194             return rc;
 195         }
 196     } while(1);
 197 
 198     return OPAL_SUCCESS;
 199 }

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