root/opal/mca/btl/usnic/btl_usnic_frag.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. usnic_frag_type
  2. usnic_seg_type_str
  3. opal_btl_usnic_small_send_frag_alloc
  4. opal_btl_usnic_large_send_frag_alloc
  5. opal_btl_usnic_put_dest_frag_alloc
  6. opal_btl_usnic_send_frag_ok_to_return
  7. opal_btl_usnic_frag_return
  8. opal_btl_usnic_send_frag_return_cond
  9. opal_btl_usnic_frag_return_cond
  10. opal_btl_usnic_chunk_segment_alloc
  11. opal_btl_usnic_chunk_segment_return
  12. opal_btl_usnic_ack_segment_alloc
  13. opal_btl_usnic_ack_segment_return
  14. opal_btl_usnic_compute_sf_size

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2006 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2006      Sandia National Laboratories. All rights
  13  *                         reserved.
  14  * Copyright (c) 2013-2019 Cisco Systems, Inc.  All rights reserved
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #ifndef OPAL_BTL_USNIC_FRAG_H
  23 #define OPAL_BTL_USNIC_FRAG_H
  24 
  25 #define OPAL_BTL_USNIC_FRAG_ALIGN (8)
  26 
  27 #include "btl_usnic.h"
  28 #include "btl_usnic_module.h"
  29 
  30 BEGIN_C_DECLS
  31 
  32 /*
  33  * Forward declarations to avoid include loops
  34  */
  35 struct opal_btl_usnic_module_t;
  36 
  37 /*
  38  * Some definitions:
  39  * frag - what the upper layer hands us to send, may be large or small
  40  * segment - one packet on the wire
  41  * chunk - when a fragment is too big to fit into one segment, it is
  42  *      broken into chunks, each chunk fitting in one segment
  43  */
  44 
  45 /**
  46  * Fragment types
  47  * The upper layer may give us very large "fragements" to send, larger than
  48  * an MTU.  We break fragments into segments for sending, a segment being
  49  * defined to fit within an MTU.
  50  */
  51 typedef enum {
  52     OPAL_BTL_USNIC_FRAG_LARGE_SEND,
  53     OPAL_BTL_USNIC_FRAG_SMALL_SEND,
  54     OPAL_BTL_USNIC_FRAG_PUT_DEST
  55 } opal_btl_usnic_frag_type_t;
  56 
  57 static inline const char *
  58 usnic_frag_type(opal_btl_usnic_frag_type_t t)
  59 {
  60     switch (t) {
  61     case OPAL_BTL_USNIC_FRAG_LARGE_SEND: return "large";
  62     case OPAL_BTL_USNIC_FRAG_SMALL_SEND: return "small";
  63     case OPAL_BTL_USNIC_FRAG_PUT_DEST: return "put dest";
  64     default: return "unknown";
  65     }
  66 }
  67 
  68 typedef enum {
  69     OPAL_BTL_USNIC_SEG_ACK,
  70     OPAL_BTL_USNIC_SEG_FRAG,
  71     OPAL_BTL_USNIC_SEG_CHUNK,
  72     OPAL_BTL_USNIC_SEG_RECV
  73 } opal_btl_usnic_seg_type_t;
  74 
  75 static inline const char *
  76 usnic_seg_type_str(opal_btl_usnic_seg_type_t t)
  77 {
  78     switch (t) {
  79     case OPAL_BTL_USNIC_SEG_ACK:   return "ACK";
  80     case OPAL_BTL_USNIC_SEG_FRAG:  return "FRAG";
  81     case OPAL_BTL_USNIC_SEG_CHUNK: return "CHUNK";
  82     case OPAL_BTL_USNIC_SEG_RECV:  return "RECV";
  83     default:                       return "unknown";
  84     }
  85 }
  86 
  87 
  88 /*
  89  * usnic registration handle (passed over the network to peers as a
  90  * cookie).
  91  *
  92  * Currently, this struct is meaningless (but it must be defined /
  93  * exist) because we are emulating RDMA and do not have
  94  * btl_register_mem and btl_deregister_mem functions (and we set
  95  * module.btl_registration_handle_size to 0, not sizeof(struct
  96  * mca_btl_base_registration_handle_t)).
  97  */
  98 struct mca_btl_base_registration_handle_t {
  99     /* Maybe we'll need fields like this */
 100     uint32_t lkey;
 101     uint32_t rkey;
 102 };
 103 
 104 /*
 105  * usnic local registration
 106  */
 107 typedef struct opal_btl_usnic_reg_t {
 108     mca_rcache_base_registration_t base;
 109     struct fid_mr *ur_mr;
 110 } opal_btl_usnic_reg_t;
 111 
 112 
 113 /**
 114  * usnic header type
 115  */
 116 typedef enum {
 117     OPAL_BTL_USNIC_PAYLOAD_TYPE_ACK = 1,
 118     OPAL_BTL_USNIC_PAYLOAD_TYPE_FRAG = 2,       /* an entire fragment */
 119     OPAL_BTL_USNIC_PAYLOAD_TYPE_CHUNK = 3       /* one chunk of fragment */
 120 } opal_btl_usnic_payload_type_t;
 121 
 122 /**
 123  * BTL header that goes after the protocol header.  Since this is not
 124  * a stream, we can put the fields in whatever order make the least
 125  * holes.
 126  */
 127 typedef struct {
 128 
 129     /* Hashed RTE process name of the sender */
 130     uint64_t sender;
 131 
 132     /* Sliding window sequence number (echoed back in an ACK). */
 133     opal_btl_usnic_seq_t pkt_seq;
 134     opal_btl_usnic_seq_t ack_seq;       /* for piggy-backing ACKs */
 135 
 136     /* payload legnth (in bytes).  We unfortunately have to include
 137        this in our header because the L2 layer may artifically inflate
 138        the length of the packet to meet a minimum size */
 139     uint16_t payload_len;
 140 
 141     /* If this is an emulated PUT, store at this address on receiver */
 142     char *put_addr;
 143 
 144     /* Type of BTL header (see enum, above) */
 145     uint8_t payload_type;
 146 
 147     /* true if there is piggy-backed ACK */
 148     uint8_t ack_present;
 149 
 150     /* tag for upper layer */
 151     mca_btl_base_tag_t tag;
 152 } opal_btl_usnic_btl_header_t;
 153 
 154 /**
 155  * BTL header for a chunk of a fragment
 156  */
 157 typedef struct {
 158     opal_btl_usnic_btl_header_t ch_hdr;
 159 
 160     uint32_t ch_frag_id;        /* ID for collecting segments of same frag */
 161     uint32_t ch_frag_size;      /* total frag len */
 162     uint32_t ch_frag_offset;    /* where in fragment this goes */
 163 } opal_btl_usnic_btl_chunk_header_t;
 164 
 165 /**
 166  * Descriptor for a common segment.  This is exactly one packet and may
 167  * be sent or received.
 168  */
 169 typedef struct opal_btl_usnic_segment_t {
 170     opal_free_list_item_t us_list;
 171 
 172     opal_btl_usnic_seg_type_t us_type;
 173 
 174     /* header for chunked frag is different */
 175     union {
 176         opal_btl_usnic_btl_header_t *uus_btl_header;
 177         opal_btl_usnic_btl_chunk_header_t *uus_btl_chunk_header;
 178     } us_hdr;
 179 #define us_btl_header us_hdr.uus_btl_header
 180 #define us_btl_chunk_header us_hdr.uus_btl_chunk_header
 181 
 182     union {
 183         uint8_t *raw;
 184         void *ompi_header;
 185     } us_payload;
 186 } opal_btl_usnic_segment_t;
 187 
 188 struct opal_btl_usnic_endpoint_t;
 189 
 190 /**
 191  * Descriptor for a recv segment.  This is exactly one packet and may
 192  * be part of a large or small send or may be an ACK
 193  */
 194 typedef struct opal_btl_usnic_recv_segment_t {
 195     opal_btl_usnic_segment_t rs_base;
 196     mca_btl_base_descriptor_t rs_desc;
 197     mca_btl_base_segment_t rs_segment;
 198 
 199     /* receive segments have protocol header prepended */
 200     uint8_t *rs_protocol_header;
 201     size_t rs_len;
 202 
 203     struct opal_btl_usnic_recv_segment_t *rs_next;
 204 
 205     opal_btl_usnic_endpoint_t *rs_endpoint;
 206 
 207 } opal_btl_usnic_recv_segment_t;
 208 
 209 /**
 210  * Descriptor for a send segment.  This is exactly one packet and may
 211  * be part of a large or small send or may be an ACK
 212  */
 213 typedef struct opal_btl_usnic_send_segment_t {
 214     opal_btl_usnic_segment_t ss_base;
 215 
 216     uint8_t *ss_ptr;
 217     size_t ss_len;
 218 
 219     /* channel upon which send was posted */
 220     opal_btl_usnic_channel_id_t ss_channel;
 221 
 222     struct opal_btl_usnic_send_frag_t *ss_parent_frag;
 223     int ss_hotel_room;          /* current retrans room, or -1 if none */
 224 
 225     /* How many times is this frag on a hardware queue? */
 226     uint32_t ss_send_posted;
 227     bool ss_ack_pending;        /* true until this segment is ACKed */
 228 
 229 } opal_btl_usnic_send_segment_t;
 230 
 231 typedef opal_btl_usnic_send_segment_t opal_btl_usnic_frag_segment_t;
 232 typedef opal_btl_usnic_send_segment_t opal_btl_usnic_chunk_segment_t;
 233 
 234 /**
 235  * Common part of usNIC fragment descriptor
 236  */
 237 typedef struct opal_btl_usnic_frag_t {
 238     mca_btl_base_descriptor_t uf_base;
 239 
 240     /* fragment descriptor type */
 241     opal_btl_usnic_frag_type_t uf_type;
 242 
 243     /* utility segments (just seg_addr/seg_len) */
 244     mca_btl_base_segment_t uf_local_seg[2];
 245     mca_btl_base_segment_t uf_remote_seg[1];
 246 
 247     /* freelist this came from */
 248     opal_free_list_t *uf_freelist;
 249 } opal_btl_usnic_frag_t;
 250 
 251 /**
 252  * Common part of usNIC send fragment descriptor
 253  */
 254 typedef struct opal_btl_usnic_send_frag_t {
 255     opal_btl_usnic_frag_t sf_base;
 256 
 257     struct mca_btl_base_endpoint_t *sf_endpoint;
 258 
 259     size_t sf_size;             /* total_fragment size (upper + user payload) */
 260 
 261     struct opal_convertor_t sf_convertor; /* copy of original message data if
 262                                              convertor required */
 263 
 264     uint32_t sf_seg_post_cnt;   /* total segs currently posted for this frag */
 265     size_t sf_ack_bytes_left;   /* bytes remaining to be ACKed */
 266 
 267     struct opal_btl_usnic_send_frag_t *sf_next;
 268 } opal_btl_usnic_send_frag_t;
 269 
 270 /**
 271  * Descriptor for a large fragment
 272  * Large fragment uses two SG entries - one points to upper layer header,
 273  * other points to data.
 274  */
 275 typedef struct opal_btl_usnic_large_send_frag_t {
 276     opal_btl_usnic_send_frag_t lsf_base;
 277 
 278     char lsf_ompi_header[64];   /* space for upper layer header */
 279     mca_btl_base_tag_t lsf_tag; /* save tag */
 280 
 281     uint32_t lsf_frag_id;       /* fragment ID for reassembly */
 282 
 283     size_t lsf_cur_offset;      /* next byte offset to be enqueued on the
 284                                    endpoint (incl. any convertor payload) */
 285     size_t lsf_bytes_left;      /* bytes remaining to give enqueue on the
 286                                    endpoint (incl. any convertor payload) */
 287     size_t lsf_pack_bytes_left; /* bytes remaining to be packed into chunk
 288                                    segments (incl. any convertor payload) */
 289     uint8_t *lsf_cur_ptr;       /* current packing pointer */
 290     int lsf_cur_sge;
 291     size_t lsf_bytes_left_in_sge;
 292 
 293     uint8_t *lsf_buffer;        /* attached storage for usnic_alloc() */
 294 
 295     opal_list_t lsf_seg_chain;  /* chain of segments for converted data */
 296 
 297     bool lsf_pack_on_the_fly;   /* true if we are packing on the fly */
 298 } opal_btl_usnic_large_send_frag_t;
 299 
 300 /* Shortcut member macros.  Access uf_src_seg array instead of the descriptor's
 301  * des_src ptr to save a deref. */
 302 #define lsf_des_src       lsf_base.sf_base.uf_local_seg
 303 
 304 /**
 305  * small send fragment
 306  * Small send will optimistically use 2 SG entries in hopes of performing
 307  * an inline send, but will convert to a single SG entry is inline cannot
 308  * be done and data must be copied.
 309  * First segment will point to registered memory of associated segment to
 310  * hold BTL and upper layer headers.
 311  * Second segment will point directly to user data.  If inlining fails, we
 312  * will copy user data into the registered memory after the upper layer header
 313  * and convert to a single segment.
 314  */
 315 typedef struct opal_btl_usnic_small_send_frag_t {
 316     opal_btl_usnic_send_frag_t ssf_base;
 317 
 318     /* small fragments have embedded segs */
 319     opal_btl_usnic_send_segment_t ssf_segment;
 320 
 321 } opal_btl_usnic_small_send_frag_t;
 322 
 323 /**
 324  * descriptor for a put destination
 325  */
 326 typedef opal_btl_usnic_frag_t opal_btl_usnic_put_dest_frag_t;
 327 
 328 /**
 329  * A simple buffer that can be enqueued on an opal_free_list_t that is intended
 330  * to be used for fragment reassembly.  Nominally the free list code supports
 331  * this via the rb_super.ptr field, but that field is only allocated and
 332  * non-NULL if an mpool is used, and we don't need this reassembly memory to be
 333  * registered.
 334  */
 335 typedef struct opal_btl_usnic_rx_buf_t {
 336     opal_free_list_item_t rb_super;
 337     char buf[1]; /* flexible array member for frag reassembly */
 338 } opal_btl_usnic_rx_buf_t;
 339 
 340 OBJ_CLASS_DECLARATION(opal_btl_usnic_send_frag_t);
 341 OBJ_CLASS_DECLARATION(opal_btl_usnic_small_send_frag_t);
 342 OBJ_CLASS_DECLARATION(opal_btl_usnic_large_send_frag_t);
 343 OBJ_CLASS_DECLARATION(opal_btl_usnic_put_dest_frag_t);
 344 
 345 OBJ_CLASS_DECLARATION(opal_btl_usnic_segment_t);
 346 OBJ_CLASS_DECLARATION(opal_btl_usnic_frag_segment_t);
 347 OBJ_CLASS_DECLARATION(opal_btl_usnic_chunk_segment_t);
 348 OBJ_CLASS_DECLARATION(opal_btl_usnic_recv_segment_t);
 349 
 350 OBJ_CLASS_DECLARATION(opal_btl_usnic_rx_buf_t);
 351 
 352 typedef opal_btl_usnic_send_segment_t opal_btl_usnic_ack_segment_t;
 353 OBJ_CLASS_DECLARATION(opal_btl_usnic_ack_segment_t);
 354 
 355 /*
 356  * Alloc a send frag from the send pool
 357  */
 358 static inline opal_btl_usnic_small_send_frag_t *
 359 opal_btl_usnic_small_send_frag_alloc(opal_btl_usnic_module_t *module)
 360 {
 361     opal_free_list_item_t *item;
 362     opal_btl_usnic_small_send_frag_t *frag;
 363 
 364     USNIC_COMPAT_FREE_LIST_GET(&(module->small_send_frags), item);
 365     if (OPAL_UNLIKELY(NULL == item)) {
 366         return NULL;
 367     }
 368 
 369     frag = (opal_btl_usnic_small_send_frag_t*) item;
 370 
 371     /* this belongs in constructor... */
 372     frag->ssf_base.sf_base.uf_freelist = &(module->small_send_frags);
 373     frag->ssf_segment.ss_send_posted = 0;
 374 
 375     assert(frag);
 376     assert(OPAL_BTL_USNIC_FRAG_SMALL_SEND == frag->ssf_base.sf_base.uf_type);
 377 
 378     return frag;
 379 }
 380 
 381 static inline opal_btl_usnic_large_send_frag_t *
 382 opal_btl_usnic_large_send_frag_alloc(opal_btl_usnic_module_t *module)
 383 {
 384     opal_free_list_item_t *item;
 385     opal_btl_usnic_large_send_frag_t *frag;
 386 
 387     USNIC_COMPAT_FREE_LIST_GET(&(module->large_send_frags), item);
 388     if (OPAL_UNLIKELY(NULL == item)) {
 389         return NULL;
 390     }
 391 
 392     frag = (opal_btl_usnic_large_send_frag_t*) item;
 393 
 394     /* this belongs in constructor... */
 395     frag->lsf_base.sf_base.uf_freelist = &(module->large_send_frags);
 396 
 397     assert(frag);
 398     assert(OPAL_BTL_USNIC_FRAG_LARGE_SEND == frag->lsf_base.sf_base.uf_type);
 399 
 400     return frag;
 401 }
 402 
 403 static inline opal_btl_usnic_put_dest_frag_t *
 404 opal_btl_usnic_put_dest_frag_alloc(
 405     struct opal_btl_usnic_module_t *module)
 406 {
 407     opal_free_list_item_t *item;
 408     opal_btl_usnic_put_dest_frag_t *frag;
 409 
 410     USNIC_COMPAT_FREE_LIST_GET(&(module->put_dest_frags), item);
 411     if (OPAL_UNLIKELY(NULL == item)) {
 412         return NULL;
 413     }
 414 
 415     frag = (opal_btl_usnic_put_dest_frag_t*) item;
 416 
 417     /* this belongs in constructor... */
 418     frag->uf_freelist = &(module->put_dest_frags);
 419 
 420     assert(frag);
 421     assert(OPAL_BTL_USNIC_FRAG_PUT_DEST == frag->uf_type);
 422 
 423     return frag;
 424 }
 425 
 426 /*
 427  * A send frag can be returned to the freelist when all of the
 428  * following are true:
 429  *
 430  * 1. upper layer is freeing it (via module.free())
 431  * 2. Or all of these:
 432  *    a) it finishes sending all its segments
 433  *    b) all of its segments have been ACKed
 434  *    c) it is owned by the BTL
 435  */
 436 static inline bool
 437 opal_btl_usnic_send_frag_ok_to_return(
 438     opal_btl_usnic_module_t *module,
 439     opal_btl_usnic_send_frag_t *frag)
 440 {
 441     assert(frag);
 442 
 443     if (OPAL_LIKELY(frag->sf_base.uf_base.des_flags &
 444                 MCA_BTL_DES_FLAGS_BTL_OWNERSHIP) &&
 445         0 == frag->sf_ack_bytes_left &&
 446         0 == frag->sf_seg_post_cnt) {
 447         return true;
 448     }
 449 
 450     return false;
 451 }
 452 
 453 static inline void
 454 opal_btl_usnic_frag_return(
 455     struct opal_btl_usnic_module_t *module,
 456     opal_btl_usnic_frag_t *frag)
 457 {
 458 #if MSGDEBUG1
 459     opal_output(0, "freeing frag %p, type %s\n", (void *)frag,
 460             usnic_frag_type(frag->uf_type));
 461 #endif
 462     frag->uf_local_seg[0].seg_len = 0;
 463     frag->uf_local_seg[1].seg_len = 0;
 464 
 465     /* If this is a large fragment, we need to free any
 466      * attached storage
 467      */
 468     if (frag->uf_type == OPAL_BTL_USNIC_FRAG_LARGE_SEND) {
 469         opal_btl_usnic_large_send_frag_t *lfrag;
 470         lfrag = (opal_btl_usnic_large_send_frag_t *)frag;
 471         if (lfrag->lsf_buffer != NULL) {
 472             free(lfrag->lsf_buffer);
 473             lfrag->lsf_buffer = NULL;
 474         }
 475         lfrag->lsf_pack_on_the_fly = false;
 476 
 477         /* JMS This should never happen any more, right? */
 478         if (2 == lfrag->lsf_base.sf_base.uf_base.USNIC_SEND_LOCAL_COUNT &&
 479             NULL == lfrag->lsf_des_src[1].seg_addr.pval) {
 480             opal_convertor_cleanup(&lfrag->lsf_base.sf_convertor);
 481         }
 482     }
 483 
 484     /* Reset the "send_posted" flag on the embedded segment for small
 485        fragments */
 486     else if (frag->uf_type == OPAL_BTL_USNIC_FRAG_SMALL_SEND) {
 487         opal_btl_usnic_small_send_frag_t *sfrag;
 488         sfrag = (opal_btl_usnic_small_send_frag_t *) frag;
 489         sfrag->ssf_segment.ss_send_posted = 0;
 490     }
 491 
 492     USNIC_COMPAT_FREE_LIST_RETURN(frag->uf_freelist, &(frag->uf_base.super));
 493 }
 494 
 495 /*
 496  * Return a send frag if it's all done and owned by BTL
 497  */
 498 static inline void
 499 opal_btl_usnic_send_frag_return_cond(
 500     struct opal_btl_usnic_module_t *module,
 501     opal_btl_usnic_send_frag_t *frag)
 502 {
 503     if (opal_btl_usnic_send_frag_ok_to_return(module, frag)) {
 504         opal_btl_usnic_frag_return(module, &frag->sf_base);
 505     }
 506 }
 507 
 508 /*
 509  * Return a frag if it's all done and owned by BTL
 510  * If this is a PUT destination, only condition is that we own it.  If it's
 511  * a send frag, there are other conditions, so use the specific send frag
 512  * return checker.
 513  */
 514 static inline void
 515 opal_btl_usnic_frag_return_cond(
 516     struct opal_btl_usnic_module_t *module,
 517     opal_btl_usnic_frag_t *frag)
 518 {
 519     if (OPAL_BTL_USNIC_FRAG_PUT_DEST == frag->uf_type) {
 520         if (OPAL_LIKELY(frag->uf_base.des_flags &
 521                                     MCA_BTL_DES_FLAGS_BTL_OWNERSHIP)) {
 522             opal_btl_usnic_frag_return(module, frag);
 523         }
 524     } else {
 525         opal_btl_usnic_send_frag_return_cond(module,
 526                 (opal_btl_usnic_send_frag_t *)frag);
 527     }
 528 }
 529 
 530 static inline opal_btl_usnic_chunk_segment_t *
 531 opal_btl_usnic_chunk_segment_alloc(
 532     opal_btl_usnic_module_t *module)
 533 {
 534     opal_free_list_item_t *item;
 535     opal_btl_usnic_send_segment_t *seg;
 536 
 537     USNIC_COMPAT_FREE_LIST_GET(&(module->chunk_segs), item);
 538     if (OPAL_UNLIKELY(NULL == item)) {
 539         return NULL;
 540     }
 541 
 542     seg = (opal_btl_usnic_send_segment_t*) item;
 543     seg->ss_channel = USNIC_DATA_CHANNEL;
 544 
 545     assert(seg);
 546     assert(OPAL_BTL_USNIC_SEG_CHUNK == seg->ss_base.us_type);
 547 
 548     return seg;
 549 }
 550 
 551 static inline void
 552 opal_btl_usnic_chunk_segment_return(
 553     opal_btl_usnic_module_t *module,
 554     opal_btl_usnic_chunk_segment_t *seg)
 555 {
 556     assert(seg);
 557     assert(OPAL_BTL_USNIC_SEG_CHUNK == seg->ss_base.us_type);
 558 
 559     USNIC_COMPAT_FREE_LIST_RETURN(&(module->chunk_segs), &(seg->ss_base.us_list));
 560 }
 561 
 562 /*
 563  * Alloc an ACK segment
 564  */
 565 static inline opal_btl_usnic_ack_segment_t *
 566 opal_btl_usnic_ack_segment_alloc(opal_btl_usnic_module_t *module)
 567 {
 568     opal_free_list_item_t *item;
 569     opal_btl_usnic_send_segment_t *ack;
 570 
 571     USNIC_COMPAT_FREE_LIST_GET(&(module->ack_segs), item);
 572     if (OPAL_UNLIKELY(NULL == item)) {
 573         return NULL;
 574     }
 575 
 576     ack = (opal_btl_usnic_ack_segment_t*) item;
 577     ack->ss_channel = USNIC_PRIORITY_CHANNEL;
 578 
 579     assert(ack);
 580     assert(OPAL_BTL_USNIC_SEG_ACK == ack->ss_base.us_type);
 581 
 582     return ack;
 583 }
 584 
 585 /*
 586  * Return an ACK segment
 587  */
 588 static inline void
 589 opal_btl_usnic_ack_segment_return(
 590     opal_btl_usnic_module_t *module,
 591     opal_btl_usnic_ack_segment_t *ack)
 592 {
 593     assert(ack);
 594     assert(OPAL_BTL_USNIC_SEG_ACK == ack->ss_base.us_type);
 595 
 596     USNIC_COMPAT_FREE_LIST_RETURN(&(module->ack_segs), &(ack->ss_base.us_list));
 597 }
 598 
 599 /* Compute and set the proper value for sfrag->sf_size.  This must not be used
 600  * during usnic_alloc, since the PML might change the segment size after
 601  * usnic_alloc returns. */
 602 static inline void
 603 opal_btl_usnic_compute_sf_size(opal_btl_usnic_send_frag_t *sfrag)
 604 {
 605     opal_btl_usnic_frag_t *frag;
 606 
 607     frag = &sfrag->sf_base;
 608 
 609     /* JMS This can be a put or a send, and the buffers are different... */
 610 #if 0
 611     assert(frag->uf_base.USNIC_SEND_LOCAL_COUNT > 0);
 612     assert(frag->uf_base.USNIC_SEND_LOCAL_COUNT <= 2);
 613 
 614     /* belt and suspenders: second len should be zero if only one SGE */
 615     assert(2 == frag->uf_base.USNIC_SEND_LOCAL_COUNT ||
 616         0 == frag->uf_local_seg[1].seg_len);
 617 #endif
 618 
 619     sfrag->sf_size = 0;
 620     sfrag->sf_size += frag->uf_local_seg[0].seg_len;
 621     sfrag->sf_size += frag->uf_local_seg[1].seg_len;
 622 }
 623 
 624 END_C_DECLS
 625 
 626 #endif

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