root/opal/mca/btl/portals4/btl_portals4.c

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

DEFINITIONS

This source file includes following definitions.
  1. btl_portals4_init_interface
  2. create_endpoint
  3. create_peer_and_endpoint
  4. create_maptable
  5. mca_btl_portals4_add_procs
  6. mca_btl_portals4_del_procs
  7. mca_btl_portals4_alloc
  8. mca_btl_portals4_free
  9. mca_btl_portals4_prepare_src
  10. mca_btl_portals4_register_mem
  11. mca_btl_portals4_deregister_mem
  12. mca_btl_portals4_finalize
  13. mca_btl_portals4_free_module

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2010-2012 Sandia National Laboratories.  All rights reserved.
  14  * Copyright (c) 2014      Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * Copyright (c) 2014      Intel, Inc. All rights reserved.
  17  * Copyright (c) 2014      Bull SAS.  All rights reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  * $HEADER$
  23  */
  24 
  25 #include "opal_config.h"
  26 
  27 #include <sys/types.h>
  28 #include <unistd.h>
  29 #include <stdio.h>
  30 #include "opal_stdint.h"
  31 
  32 #include "opal/class/opal_bitmap.h"
  33 #include "opal/constants.h"
  34 #include "opal/mca/btl/btl.h"
  35 #include "opal/datatype/opal_convertor.h"
  36 #include "opal/util/proc.h"
  37 #include "opal/mca/pmix/pmix.h"
  38 
  39 #include "btl_portals4.h"
  40 #include "btl_portals4_recv.h"
  41 
  42 
  43 mca_btl_base_registration_handle_t *
  44 mca_btl_portals4_register_mem(mca_btl_base_module_t *btl,
  45                               mca_btl_base_endpoint_t *endpoint,
  46                               void *base,
  47                               size_t size,
  48                               uint32_t flags);
  49 
  50 int mca_btl_portals4_deregister_mem(mca_btl_base_module_t *btl,
  51                                     mca_btl_base_registration_handle_t *handle);
  52 
  53 mca_btl_portals4_module_t mca_btl_portals4_module = {
  54     .super = {
  55         .btl_component = &mca_btl_portals4_component.super,
  56 
  57         /* NOTE: All the default values are set in
  58            component_open() */
  59 
  60         .btl_add_procs = mca_btl_portals4_add_procs,
  61         .btl_del_procs = mca_btl_portals4_del_procs,
  62         .btl_finalize = mca_btl_portals4_finalize,
  63         .btl_alloc = mca_btl_portals4_alloc,
  64         .btl_free = mca_btl_portals4_free,
  65         .btl_prepare_src = mca_btl_portals4_prepare_src,
  66         .btl_register_mem = mca_btl_portals4_register_mem,
  67         .btl_deregister_mem = mca_btl_portals4_deregister_mem,
  68         .btl_send = mca_btl_portals4_send,
  69         .btl_get = mca_btl_portals4_get,
  70         .btl_dump = mca_btl_base_dump,
  71     },
  72 };
  73 
  74 static int
  75 btl_portals4_init_interface(void)
  76 {
  77     mca_btl_portals4_module_t *portals4_btl;
  78     unsigned int ret, interface;
  79     ptl_md_t md;
  80     ptl_me_t me;
  81 
  82 // The initialisation of EQ, PT and ME must be done after the SetMap !
  83     for (interface=0; interface<mca_btl_portals4_component.num_btls; interface++) {
  84         portals4_btl = mca_btl_portals4_component.btls[interface];
  85 
  86         /* create event queue */
  87         ret = PtlEQAlloc(portals4_btl->portals_ni_h,
  88                      mca_btl_portals4_component.recv_queue_size,
  89                      &portals4_btl->recv_eq_h);
  90         if (PTL_OK != ret) {
  91             opal_output_verbose(1, opal_btl_base_framework.framework_output,
  92                             "%s:%d: PtlEQAlloc failed for NI %d: %d",
  93                             __FILE__, __LINE__, interface, ret);
  94             goto error;
  95         }
  96         mca_btl_portals4_component.eqs_h[interface] = portals4_btl->recv_eq_h;
  97         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
  98             "PtlEQAlloc (recv_eq=%d) OK for NI %d\n", portals4_btl->recv_eq_h, interface));
  99 
 100         /* Create recv_idx portal table entry */
 101         ret = PtlPTAlloc(portals4_btl->portals_ni_h,
 102                      PTL_PT_ONLY_TRUNCATE,
 103                      portals4_btl->recv_eq_h,
 104                      REQ_BTL_TABLE_ID,
 105                      &portals4_btl->recv_idx);
 106         if (PTL_OK != ret) {
 107             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 108                             "%s:%d: PtlPTAlloc failed for NI %d: %d",
 109                             __FILE__, __LINE__, interface, ret);
 110             goto error;
 111         }
 112         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 113             "PtlPTAlloc (recv_idx) OK for NI %d recv_idx=%d", interface, portals4_btl->recv_idx));
 114 
 115         if (portals4_btl->recv_idx != REQ_BTL_TABLE_ID) {
 116             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 117                             "%s:%d: PtlPTAlloc did not allocate the requested PT: %d",
 118                            __FILE__, __LINE__, portals4_btl->recv_idx);
 119             goto error;
 120         }
 121 
 122         /* bind zero-length md for sending acks */
 123         md.start     = NULL;
 124         md.length    = 0;
 125         md.options   = 0;
 126         md.eq_handle = PTL_EQ_NONE;
 127         md.ct_handle = PTL_CT_NONE;
 128 
 129         ret = PtlMDBind(portals4_btl->portals_ni_h,
 130                     &md,
 131                     &portals4_btl->zero_md_h);
 132         if (PTL_OK != ret) {
 133             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 134                             "%s:%d: PtlMDBind failed for NI %d: %d",
 135                             __FILE__, __LINE__, interface, ret);
 136             goto error;
 137         }
 138         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 139             "PtlMDBind (zero-length md=%d) OK for NI %d", portals4_btl->zero_md_h, interface));
 140 
 141         /* Bind MD across all memory */
 142         md.start = 0;
 143         md.length = PTL_SIZE_MAX;
 144         md.options = 0;
 145         md.eq_handle = portals4_btl->recv_eq_h;
 146         md.ct_handle = PTL_CT_NONE;
 147 
 148         ret = PtlMDBind(portals4_btl->portals_ni_h,
 149                     &md,
 150                     &portals4_btl->send_md_h);
 151         if (PTL_OK != ret) {
 152             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 153                             "%s:%d: PtlMDBind failed for NI %d: %d\n",
 154                             __FILE__, __LINE__, interface, ret);
 155             goto error;
 156         }
 157 
 158         /* Handle long overflows */
 159         me.start = NULL;
 160         me.length = 0;
 161         me.ct_handle = PTL_CT_NONE;
 162         me.min_free = 0;
 163         me.uid = PTL_UID_ANY;
 164         me.options = PTL_ME_OP_PUT |
 165             PTL_ME_EVENT_LINK_DISABLE |
 166             PTL_ME_EVENT_COMM_DISABLE |
 167             PTL_ME_EVENT_UNLINK_DISABLE;
 168         if (mca_btl_portals4_component.use_logical) {
 169             me.match_id.rank = PTL_RANK_ANY;
 170         } else {
 171             me.match_id.phys.nid = PTL_NID_ANY;
 172             me.match_id.phys.pid = PTL_PID_ANY;
 173         }
 174         me.match_bits = BTL_PORTALS4_LONG_MSG;
 175         me.ignore_bits = BTL_PORTALS4_CONTEXT_MASK |
 176             BTL_PORTALS4_SOURCE_MASK |
 177             BTL_PORTALS4_TAG_MASK;
 178         ret = PtlMEAppend(portals4_btl->portals_ni_h,
 179                       portals4_btl->recv_idx,
 180                       &me,
 181                       PTL_OVERFLOW_LIST,
 182                       NULL,
 183                       &portals4_btl->long_overflow_me_h);
 184         if (PTL_OK != ret) {
 185             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 186                             "%s:%d: PtlMEAppend failed for NI %d: %d",
 187                             __FILE__, __LINE__, interface, ret);
 188             goto error;
 189         }
 190         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlMEAppend (overflow list) OK for NI %d", interface));
 191     }
 192 
 193     ret = mca_btl_portals4_recv_enable(portals4_btl);
 194     if (PTL_OK != ret) {
 195         opal_output_verbose(1, opal_btl_base_framework.framework_output,
 196                             "%s:%d: Initialization of recv buffer failed: %d",
 197                             __FILE__, __LINE__, ret);
 198         goto error;
 199     }
 200 
 201     return OPAL_SUCCESS;
 202 
 203  error:
 204     opal_output_verbose(1, opal_btl_base_framework.framework_output, "Error in btl_portals4_init_interface");
 205 
 206     for (interface=0; interface<mca_btl_portals4_component.num_btls; interface++) {
 207         portals4_btl = mca_btl_portals4_component.btls[interface];
 208         if (NULL != portals4_btl) mca_btl_portals4_free_module(portals4_btl);
 209     }
 210     mca_btl_portals4_component.num_btls = 0;
 211     if (NULL != mca_btl_portals4_component.btls)  free(mca_btl_portals4_component.btls);
 212     if (NULL != mca_btl_portals4_component.eqs_h) free(mca_btl_portals4_component.eqs_h);
 213     mca_btl_portals4_component.btls = NULL;
 214     mca_btl_portals4_component.eqs_h = NULL;
 215 
 216     return OPAL_ERROR;
 217 }
 218 
 219 static int
 220 create_endpoint(int                       interface,
 221                 opal_proc_t              *proc,
 222                 mca_btl_base_endpoint_t **endpoint)
 223 {
 224     int ret;
 225     size_t size;
 226     ptl_process_t *id;
 227 
 228     OPAL_MODEX_RECV(ret, &mca_btl_portals4_component.super.btl_version,
 229                     &proc->proc_name, (void**) &id, &size);
 230 
 231     if (OPAL_ERR_NOT_FOUND == ret) {
 232         OPAL_OUTPUT_VERBOSE((30, opal_btl_base_framework.framework_output,
 233             "btl/portals4: Portals 4 BTL not available on peer: %s", opal_strerror(ret)));
 234         return ret;
 235     } else if (OPAL_SUCCESS != ret) {
 236         opal_output_verbose(0, opal_btl_base_framework.framework_output,
 237             "btl/portals4: opal_modex_recv failed: %s", opal_strerror(ret));
 238         return ret;
 239     }
 240     if (size < sizeof(ptl_process_t)) {  /* no available connection */
 241         return OPAL_ERROR;
 242     }
 243     if ((size % sizeof(ptl_process_t)) != 0) {
 244         opal_output_verbose(0, opal_btl_base_framework.framework_output,
 245             "btl/portals4: invalid format in modex");
 246         return OPAL_ERROR;
 247     }
 248     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 249         "btl/portals4: %d NI(s) declared in the modex", (int) (size/sizeof(ptl_process_t))));
 250 
 251     *endpoint = malloc(sizeof(mca_btl_base_endpoint_t));
 252     if (NULL == *endpoint) {
 253         return OPAL_ERR_OUT_OF_RESOURCE;
 254     }
 255 
 256     (*endpoint)->ptl_proc = id[interface];
 257 
 258     return OPAL_SUCCESS;
 259 }
 260 
 261 static int
 262 create_peer_and_endpoint(int                       interface,
 263                          opal_proc_t              *proc,
 264                          ptl_process_t            *phys_peer,
 265                          mca_btl_base_endpoint_t **endpoint)
 266 {
 267     int ret;
 268     size_t size;
 269     ptl_process_t *id;
 270 
 271     OPAL_MODEX_RECV(ret, &mca_btl_portals4_component.super.btl_version,
 272                     &proc->proc_name, (void**) &id, &size);
 273 
 274     if (OPAL_ERR_NOT_FOUND == ret) {
 275         OPAL_OUTPUT_VERBOSE((30, opal_btl_base_framework.framework_output,
 276             "btl/portals4: Portals 4 BTL not available on peer: %s", opal_strerror(ret)));
 277         return ret;
 278     } else if (OPAL_SUCCESS != ret) {
 279         opal_output_verbose(0, opal_btl_base_framework.framework_output,
 280             "btl/portals4: opal_modex_recv failed: %s", opal_strerror(ret));
 281         return ret;
 282     }
 283     if (size < sizeof(ptl_process_t)) {  /* no available connection */
 284         return OPAL_ERROR;
 285     }
 286     if ((size % sizeof(ptl_process_t)) != 0) {
 287         opal_output_verbose(0, opal_btl_base_framework.framework_output,
 288             "btl/portals4: invalid format in modex");
 289         return OPAL_ERROR;
 290     }
 291     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 292         "btl/portals4: %d NI(s) declared in the modex", (int) (size/sizeof(ptl_process_t))));
 293 
 294     /*
 295      * check if create_endpoint() already created the endpoint.
 296      * if not, create it here.
 297      */
 298     if (NULL == *endpoint) {
 299         *endpoint = malloc(sizeof(mca_btl_base_endpoint_t));
 300         if (NULL == *endpoint) {
 301             return OPAL_ERR_OUT_OF_RESOURCE;
 302         }
 303     }
 304     /*
 305      * regardless of who created the endpoint, set the rank here
 306      * because we are using logical mapping.
 307      */
 308     (*endpoint)->ptl_proc.rank = proc->proc_name.vpid;
 309 
 310     phys_peer->phys.pid = id[interface].phys.pid;
 311     phys_peer->phys.nid = id[interface].phys.nid;
 312     opal_output_verbose(50, opal_btl_base_framework.framework_output,
 313         "logical: global rank=%d pid=%d nid=%d\n",
 314         proc->proc_name.vpid, phys_peer->phys.pid, phys_peer->phys.nid);
 315 
 316     return OPAL_SUCCESS;
 317 }
 318 
 319 static int
 320 create_maptable(struct mca_btl_portals4_module_t *portals4_btl,
 321                 size_t                            nprocs,
 322                 opal_proc_t                     **procs,
 323                 mca_btl_base_endpoint_t         **endpoint)
 324 {
 325     int ret;
 326     ptl_process_t *maptable;
 327 
 328     maptable = malloc(sizeof(ptl_process_t) * nprocs);
 329     if (NULL == maptable) {
 330         opal_output_verbose(1, opal_btl_base_framework.framework_output,
 331                             "%s:%d: malloc failed\n",
 332                             __FILE__, __LINE__);
 333         return OPAL_ERR_OUT_OF_RESOURCE;
 334     }
 335 
 336     for (uint32_t i = 0 ; i < nprocs ; i++) {
 337         struct opal_proc_t *curr_proc;
 338 
 339         curr_proc = procs[i];
 340 
 341         /* portals doesn't support heterogeneous yet... */
 342         if (opal_proc_local_get()->proc_arch != curr_proc->proc_arch) {
 343             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 344                                 "Portals 4 BTL does not support heterogeneous operations.");
 345             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 346                 "Proc %s architecture %x, mine %x.",
 347                 OPAL_NAME_PRINT(curr_proc->proc_name),
 348                 curr_proc->proc_arch, opal_proc_local_get()->proc_arch);
 349             return OPAL_ERR_NOT_SUPPORTED;
 350         }
 351 
 352         ret = create_peer_and_endpoint(portals4_btl->interface_num,
 353                                        curr_proc,
 354                                        &maptable[i],
 355                                        &endpoint[i]);
 356         if (OPAL_SUCCESS != ret) {
 357             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 358                                 "%s:%d: create_maptable::create_peer_and_endpoint failed: %d\n",
 359                                 __FILE__, __LINE__, ret);
 360             return ret;
 361         }
 362     }
 363 
 364     ret = PtlSetMap(portals4_btl->portals_ni_h,
 365                     nprocs,
 366                     maptable);
 367     if (OPAL_SUCCESS != ret) {
 368         opal_output_verbose(1, opal_btl_base_framework.framework_output,
 369                             "%s:%d: logical mapping failed: %d\n",
 370                             __FILE__, __LINE__, ret);
 371         return ret;
 372     }
 373     opal_output_verbose(90, opal_btl_base_framework.framework_output,
 374         "logical mapping OK\n");
 375     free(maptable);
 376 
 377     return OPAL_SUCCESS;
 378 }
 379 
 380 #define NEED_ALL_PROCS (mca_btl_portals4_component.use_logical)
 381 
 382 int
 383 mca_btl_portals4_add_procs(struct mca_btl_base_module_t* btl_base,
 384                           size_t nprocs,
 385                           struct opal_proc_t **procs,
 386                           struct mca_btl_base_endpoint_t** btl_peer_data,
 387                           opal_bitmap_t* reachable)
 388 {
 389     struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
 390     int ret;
 391     size_t i;
 392 
 393     opal_output_verbose(50, opal_btl_base_framework.framework_output,
 394                         "mca_btl_portals4_add_procs: Adding %d procs (%d) for NI %d",
 395                         (int) nprocs,
 396                         (int) portals4_btl->portals_num_procs,
 397                         portals4_btl->interface_num);
 398 
 399     /*
 400      * The PML handed us a list of procs that need Portals4
 401      * peer info.  Complete those procs here.
 402      */
 403     for (i = 0 ; i < nprocs ; ++i) {
 404         struct opal_proc_t *curr_proc = procs[i];
 405 
 406         /* portals doesn't support heterogeneous yet... */
 407         if (opal_proc_local_get()->proc_arch != curr_proc->proc_arch) {
 408             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 409                                 "Portals 4 BTL does not support heterogeneous operations.");
 410             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 411                 "Proc %s architecture %x, mine %x.",
 412                 OPAL_NAME_PRINT(curr_proc->proc_name),
 413                 curr_proc->proc_arch, opal_proc_local_get()->proc_arch);
 414             return OPAL_ERR_NOT_SUPPORTED;
 415         }
 416 
 417         ret = create_endpoint(portals4_btl->interface_num,
 418                               curr_proc,
 419                               &btl_peer_data[i]);
 420 
 421         OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_num_procs, 1);
 422         /* and here we can reach */
 423         opal_bitmap_set_bit(reachable, i);
 424 
 425         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 426             "add_procs: rank=%lx nid=%x pid=%x for NI %d",
 427             i,
 428             btl_peer_data[i]->ptl_proc.phys.nid,
 429             btl_peer_data[i]->ptl_proc.phys.pid,
 430             portals4_btl->interface_num));
 431     }
 432 
 433     if (mca_btl_portals4_component.need_init && portals4_btl->portals_num_procs > 0) {
 434         if (mca_btl_portals4_component.use_logical) {
 435             ret = create_maptable(portals4_btl, nprocs, procs, btl_peer_data);
 436             if (OPAL_SUCCESS != ret) {
 437                 opal_output_verbose(1, opal_btl_base_framework.framework_output,
 438                                     "%s:%d: mca_btl_portals4_add_procs::create_maptable() failed: %d\n",
 439                                     __FILE__, __LINE__, ret);
 440                 return ret;
 441             }
 442         }
 443 
 444         ret = btl_portals4_init_interface();
 445         if (OPAL_SUCCESS != ret) {
 446             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 447                                 "%s:%d: portals4 interface initialization failed: %d",
 448                                 __FILE__, __LINE__, ret);
 449             return ret;
 450         }
 451         mca_btl_portals4_component.need_init = 0;
 452     }
 453 
 454     return OPAL_SUCCESS;
 455 }
 456 
 457 
 458 int
 459 mca_btl_portals4_del_procs(struct mca_btl_base_module_t *btl,
 460                           size_t nprocs,
 461                           struct opal_proc_t **procs,
 462                           struct mca_btl_base_endpoint_t **btl_peer_data)
 463 {
 464     struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl;
 465     size_t i;
 466 
 467     opal_output_verbose(50, opal_btl_base_framework.framework_output,
 468                         "mca_btl_portals4_del_procs: Removing %d procs (%d)", (int) nprocs,
 469                         (int) portals4_btl->portals_num_procs);
 470 
 471     /* See comment in btl_portals4_endpoint.h about why we look at the
 472        portals4 entry in proc_endpoints instead of the peer_data */
 473     for (i = 0 ; i < nprocs ; ++i) {
 474         free(btl_peer_data[i]);
 475         OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_num_procs, -1);
 476     }
 477 
 478     return OPAL_SUCCESS;
 479 }
 480 
 481 mca_btl_base_descriptor_t*
 482 mca_btl_portals4_alloc(struct mca_btl_base_module_t* btl_base,
 483                       struct mca_btl_base_endpoint_t* endpoint,
 484                       uint8_t order,
 485                       size_t size,
 486                       uint32_t flags)
 487 {
 488     struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
 489     mca_btl_portals4_frag_t* frag;
 490 
 491     if (size <= portals4_btl->super.btl_eager_limit) {
 492         OPAL_BTL_PORTALS4_FRAG_ALLOC_EAGER(portals4_btl, frag);
 493         if (NULL == frag) return NULL;
 494         frag->segments[0].base.seg_len = size;
 495     } else {
 496         OPAL_BTL_PORTALS4_FRAG_ALLOC_MAX(portals4_btl, frag);
 497         if (NULL == frag) return NULL;
 498         frag->segments[0].base.seg_len =
 499             size <= portals4_btl->super.btl_max_send_size ?
 500             size : portals4_btl->super.btl_max_send_size ;
 501     }
 502 
 503     frag->base.des_segment_count = 1;
 504     frag->base.des_flags = flags | MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
 505     frag->base.order = MCA_BTL_NO_ORDER;
 506 
 507     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 508         "mca_btl_portals4_alloc: %p\n", (void *) &frag->base));
 509     return &frag->base;
 510 }
 511 
 512 int
 513 mca_btl_portals4_free(struct mca_btl_base_module_t* btl_base,
 514                       mca_btl_base_descriptor_t* des)
 515 {
 516     struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
 517     mca_btl_portals4_frag_t* frag = (mca_btl_portals4_frag_t*) des;
 518 
 519     if (BTL_PORTALS4_FRAG_TYPE_EAGER == frag->type) {
 520         /* don't ever unlink eager frags */
 521         OPAL_BTL_PORTALS4_FRAG_RETURN_EAGER(portals4_btl, frag);
 522 
 523     } else if (BTL_PORTALS4_FRAG_TYPE_MAX == frag->type) {
 524         if (frag->me_h != PTL_INVALID_HANDLE) {
 525             frag->me_h = PTL_INVALID_HANDLE;
 526         }
 527         OPAL_BTL_PORTALS4_FRAG_RETURN_MAX(portals4_btl, frag);
 528 
 529     } else if (BTL_PORTALS4_FRAG_TYPE_USER == frag->type) {
 530         if (frag->me_h != PTL_INVALID_HANDLE) {
 531             frag->me_h = PTL_INVALID_HANDLE;
 532         }
 533         OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_outstanding_ops, -1);
 534         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 535             "mca_btl_portals4_free: Decrementing portals_outstanding_ops=%d\n", portals4_btl->portals_outstanding_ops));
 536         OPAL_BTL_PORTALS4_FRAG_RETURN_USER(portals4_btl, frag);
 537     } else {
 538         return OPAL_ERR_BAD_PARAM;
 539     }
 540 
 541     return OPAL_SUCCESS;
 542 }
 543 
 544 /**
 545  * Pack data and return a descriptor that can be
 546  * used for send/put.
 547  *
 548  * @param btl (IN)      BTL module
 549  * @param peer (IN)     BTL peer addressing
 550  */
 551 
 552 mca_btl_base_descriptor_t*
 553 mca_btl_portals4_prepare_src(struct mca_btl_base_module_t* btl_base,
 554                             struct mca_btl_base_endpoint_t* peer,
 555                             struct opal_convertor_t* convertor,
 556                             uint8_t order,
 557                             size_t reserve,
 558                             size_t* size,
 559                             uint32_t flags)
 560 {
 561     struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
 562     mca_btl_portals4_frag_t* frag;
 563     size_t max_data = *size;
 564     struct iovec iov;
 565     uint32_t iov_count = 1;
 566     int ret;
 567 
 568     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 569         "mca_btl_portals4_prepare_src NI=%d reserve=%ld size=%ld max_data=%ld\n", portals4_btl->interface_num, reserve, *size, max_data));
 570 
 571     if (0 != reserve || 0 != opal_convertor_need_buffers(convertor)) {
 572         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "mca_btl_portals4_prepare_src NEED BUFFERS or RESERVE\n"));
 573         frag = (mca_btl_portals4_frag_t*) mca_btl_portals4_alloc(btl_base, peer, MCA_BTL_NO_ORDER, max_data + reserve, flags);
 574         if (NULL == frag)  {
 575             return NULL;
 576         }
 577 
 578         if (max_data + reserve > frag->size) {
 579             max_data = frag->size - reserve;
 580         }
 581         iov.iov_len = max_data;
 582         iov.iov_base = (unsigned char*) frag->segments[0].base.seg_addr.pval + reserve;
 583         ret = opal_convertor_pack(convertor, &iov, &iov_count, &max_data );
 584 
 585         *size  = max_data;
 586         if (ret < 0) {
 587             mca_btl_portals4_free(btl_base, (mca_btl_base_descriptor_t *) frag);
 588             return NULL;
 589         }
 590 
 591         frag->segments[0].base.seg_len = max_data + reserve;
 592         frag->base.des_segment_count = 1;
 593     }
 594 
 595     frag->base.des_segments = &frag->segments[0].base;
 596     frag->base.des_flags = flags | MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
 597     frag->base.order = MCA_BTL_NO_ORDER;
 598     return &frag->base;
 599 }
 600 
 601 mca_btl_base_registration_handle_t *
 602 mca_btl_portals4_register_mem(mca_btl_base_module_t *btl_base,
 603                               mca_btl_base_endpoint_t *endpoint,
 604                               void *base,
 605                               size_t size,
 606                               uint32_t flags)
 607 {
 608     struct mca_btl_portals4_module_t   *portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
 609     mca_btl_base_registration_handle_t *handle = NULL;
 610     ptl_me_t me;
 611     int ret;
 612 
 613     handle = (mca_btl_base_registration_handle_t *)malloc(sizeof(mca_btl_base_registration_handle_t));
 614     if (!handle) {
 615         return NULL;
 616     }
 617 
 618     handle->key = OPAL_THREAD_ADD_FETCH64(&(portals4_btl->portals_rdma_key), 1);
 619     handle->remote_offset = 0;
 620 
 621     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 622         "mca_btl_portals4_register_mem NI=%d base=%p size=%ld handle=%p key=%ld flags=%d",
 623         portals4_btl->interface_num, base, size, (void *)handle, handle->key, flags));
 624 
 625     /* create a match entry */
 626     me.start = base;
 627     me.length = size;
 628     me.ct_handle = PTL_CT_NONE;
 629     me.min_free = 0;
 630     me.uid = PTL_UID_ANY;
 631     me.options = PTL_ME_OP_GET |
 632         PTL_ME_EVENT_LINK_DISABLE |
 633         PTL_ME_EVENT_COMM_DISABLE |
 634         PTL_ME_EVENT_UNLINK_DISABLE;
 635 
 636     if (mca_btl_portals4_component.use_logical) {
 637         me.match_id.rank = endpoint->ptl_proc.rank;
 638     } else {
 639         me.match_id.phys.nid = endpoint->ptl_proc.phys.nid;
 640         me.match_id.phys.pid = endpoint->ptl_proc.phys.pid;
 641     }
 642     me.match_bits = handle->key;
 643     me.ignore_bits = BTL_PORTALS4_PROTOCOL_MASK |
 644         BTL_PORTALS4_CONTEXT_MASK |
 645         BTL_PORTALS4_SOURCE_MASK;
 646     me.ignore_bits = 0;
 647 
 648     ret = PtlMEAppend(portals4_btl->portals_ni_h,
 649                       portals4_btl->recv_idx,
 650                       &me,
 651                       PTL_PRIORITY_LIST,
 652                       handle,
 653                       &(handle->me_h));
 654     if (PTL_OK != ret) {
 655         opal_output_verbose(1, opal_btl_base_framework.framework_output,
 656                             "%s:%d: PtlMEAppend failed: %d\n",
 657                             __FILE__, __LINE__, ret);
 658         OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_outstanding_ops, -1);
 659         return NULL;
 660     }
 661     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 662         "PtlMEAppend (mca_btl_portals4_register_mem) handle=%p, me_h=%d start=%p length=%ld rank=%x nid=%x pid=%x match_bits=%lx\n",
 663         (void *)handle, handle->me_h, me.start, me.length,
 664         me.match_id.rank, me.match_id.phys.nid, me.match_id.phys.pid, me.match_bits));
 665     return handle;
 666 }
 667 
 668 int
 669 mca_btl_portals4_deregister_mem(mca_btl_base_module_t *btl_base,
 670                                 mca_btl_base_registration_handle_t *handle)
 671 {
 672     int ret;
 673     struct mca_btl_portals4_module_t   *portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
 674 
 675     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 676         "mca_btl_portals4_deregister_mem NI=%d handle=%p key=%ld me_h=%d\n",
 677         portals4_btl->interface_num, (void *)handle, handle->key, handle->me_h));
 678 
 679     if (!PtlHandleIsEqual(handle->me_h, PTL_INVALID_HANDLE)) {
 680         ret = PtlMEUnlink(handle->me_h);
 681         if (PTL_OK !=  ret) {
 682             opal_output_verbose(1, opal_btl_base_framework.framework_output,
 683                 "%s:%d: PtlMEUnlink failed: %d\n",__FILE__, __LINE__, ret);
 684             return OPAL_ERROR;
 685         }
 686         handle->me_h = PTL_INVALID_HANDLE;
 687     }
 688 
 689     free(handle);
 690 
 691     return OPAL_SUCCESS;
 692 }
 693 
 694 int
 695 mca_btl_portals4_finalize(struct mca_btl_base_module_t *btl)
 696 {
 697     struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl;
 698 
 699     mca_btl_portals4_free_module(portals4_btl);
 700 
 701     OBJ_DESTRUCT(&portals4_btl->portals_frag_eager);
 702     OBJ_DESTRUCT(&portals4_btl->portals_frag_max);
 703     OBJ_DESTRUCT(&portals4_btl->portals_frag_user);
 704     OBJ_DESTRUCT(&portals4_btl->portals_recv_blocks);
 705 
 706     free(portals4_btl);
 707 
 708     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 709         "mca_btl_portals4_finalize NI %d: OK\n", portals4_btl->interface_num));
 710 
 711     return OPAL_SUCCESS;
 712 }
 713 
 714 void mca_btl_portals4_free_module(mca_btl_portals4_module_t *portals4_btl)
 715 {
 716     int ret;
 717 
 718     OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 719          "mca_btl_portals4_free_module portals_outstanding_ops=%d\n", portals4_btl->portals_outstanding_ops));
 720 
 721     /* sanity check */
 722     assert(portals4_btl->portals_outstanding_ops  >= 0);
 723 
 724     /* finalize all communication */
 725     while (portals4_btl->portals_outstanding_ops > 0) {
 726         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
 727                             "mca_btl_portals4_free_module portals_outstanding_ops: %d",
 728                             portals4_btl->portals_outstanding_ops));
 729 
 730         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Call to mca_btl_portals4_component_progress (3)\n"));
 731         mca_btl_portals4_component_progress();
 732     }
 733 
 734     if (!PtlHandleIsEqual(portals4_btl->send_md_h, PTL_INVALID_HANDLE)) {
 735         PtlMDRelease(portals4_btl->send_md_h);
 736         portals4_btl->send_md_h = PTL_INVALID_HANDLE;
 737     }
 738     if (!PtlHandleIsEqual(portals4_btl->zero_md_h, PTL_INVALID_HANDLE)) {
 739         PtlMDRelease(portals4_btl->zero_md_h);
 740         portals4_btl->zero_md_h = PTL_INVALID_HANDLE;
 741     }
 742 
 743     if (!PtlHandleIsEqual(portals4_btl->long_overflow_me_h, PTL_INVALID_HANDLE)) {
 744         PtlMEUnlink(portals4_btl->long_overflow_me_h);
 745         portals4_btl->long_overflow_me_h = PTL_INVALID_HANDLE;
 746     }
 747 
 748     if ((ptl_pt_index_t) ~0UL != mca_btl_portals4_module.recv_idx) {
 749         PtlPTFree(portals4_btl->portals_ni_h, portals4_btl->recv_idx);
 750         portals4_btl->recv_idx= (ptl_pt_index_t) ~0UL;
 751     }
 752 
 753     if (PTL_EQ_NONE != portals4_btl->recv_eq_h) {
 754         ret = PtlEQFree(portals4_btl->recv_eq_h);
 755         if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error freeing EQ recv: %d", ret));
 756         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlEQFree: recv_eq_h=%d portals4_btl=%p",
 757             portals4_btl->recv_eq_h, (void*)portals4_btl));
 758 
 759         portals4_btl->recv_eq_h = PTL_EQ_NONE;
 760     }
 761     if (!PtlHandleIsEqual(portals4_btl->portals_ni_h, PTL_INVALID_HANDLE)) {
 762         ret = PtlNIFini(portals4_btl->portals_ni_h);
 763         if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error returned by PtlNIFini: %d\n", ret));
 764         OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlNIFini: portals_ni_h=%d portals4_btl=%p",
 765             portals4_btl->portals_ni_h, (void*)portals4_btl));
 766 
 767         portals4_btl->portals_ni_h = PTL_INVALID_HANDLE;
 768     }
 769     ret = mca_btl_portals4_recv_disable(portals4_btl);
 770     if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error freeing recv list: %d", ret));
 771 }

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