2011-11-02 15:07:57 +00:00
|
|
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
2011-10-27 20:22:46 +00:00
|
|
|
/*
|
2013-07-11 20:54:12 +00:00
|
|
|
* Copyright (c) 2011-2013 Los Alamos National Security, LLC.
|
2011-10-27 20:22:46 +00:00
|
|
|
* All rights reserved.
|
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if !defined(MCA_BTL_VADER_FBOX_H)
|
|
|
|
#define MCA_BTL_VADER_FBOX_H
|
|
|
|
|
|
|
|
#include "btl_vader.h"
|
|
|
|
#include "btl_vader_endpoint.h"
|
2013-07-11 20:54:12 +00:00
|
|
|
#include "btl_vader_xpmem.h"
|
|
|
|
|
|
|
|
/* these hard-coded settings are based on the ideal setup for an Opteron 61xx chip and
|
|
|
|
* may need to be adjusted for other systems. adding an MCA variable is possible but
|
|
|
|
* can cost 20-40 ns on the fast path. this size is limited to 256 maximum bytes */
|
|
|
|
#define MCA_BTL_VADER_FBOX_SIZE 64
|
|
|
|
/* there should be a power of two number of fast boxes to simplify the math in the
|
|
|
|
* critical path */
|
|
|
|
#define MCA_BTL_VADER_LAST_FBOX 63
|
|
|
|
/* two bytes are reserved for tag and size */
|
|
|
|
#define MCA_BTL_VADER_FBOX_MAX_SIZE (MCA_BTL_VADER_FBOX_SIZE - 2)
|
|
|
|
/* total size of all the fast boxes assigned to a particular peer */
|
|
|
|
#define MCA_BTL_VADER_FBOX_PEER_SIZE (MCA_BTL_VADER_FBOX_SIZE * (MCA_BTL_VADER_LAST_FBOX + 1))
|
|
|
|
|
|
|
|
enum {MCA_BTL_VADER_FBOX_FREE = 0, MCA_BTL_VADER_FBOX_RESERVED = 0x80};
|
|
|
|
|
|
|
|
#define MCA_BTL_VADER_FBOX_OUT_PTR(ep, fbox) ((ep)->fbox_out + MCA_BTL_VADER_FBOX_SIZE * (fbox))
|
|
|
|
#define MCA_BTL_VADER_FBOX_IN_PTR(ep, fbox) ((ep)->fbox_in + MCA_BTL_VADER_FBOX_SIZE * (fbox))
|
|
|
|
#define MCA_BTL_VADER_NEXT_FBOX(fbox) (((fbox) + 1) & MCA_BTL_VADER_LAST_FBOX)
|
|
|
|
|
|
|
|
static inline unsigned char * restrict mca_btl_vader_reserve_fbox (struct mca_btl_base_endpoint_t *ep, const size_t size)
|
2011-10-27 20:22:46 +00:00
|
|
|
{
|
2013-07-11 20:54:12 +00:00
|
|
|
const int next_fbox = ep->next_fbox_out;
|
|
|
|
unsigned char * restrict fbox = (unsigned char * restrict) MCA_BTL_VADER_FBOX_OUT_PTR(ep, next_fbox);
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2012-02-22 20:53:49 +00:00
|
|
|
/* todo -- need thread locks/atomics here for the multi-threaded case */
|
2013-07-11 20:54:12 +00:00
|
|
|
if (OPAL_LIKELY(size <= MCA_BTL_VADER_FBOX_MAX_SIZE && fbox[0] == MCA_BTL_VADER_FBOX_FREE)) {
|
|
|
|
/* mark this fast box as in use */
|
|
|
|
fbox[0] = MCA_BTL_VADER_FBOX_RESERVED;
|
|
|
|
|
|
|
|
ep->next_fbox_out = MCA_BTL_VADER_NEXT_FBOX(next_fbox);
|
|
|
|
return fbox + 2;
|
|
|
|
} else if (OPAL_LIKELY(size <= (MCA_BTL_VADER_FBOX_MAX_SIZE + MCA_BTL_VADER_FBOX_SIZE) && MCA_BTL_VADER_LAST_FBOX != next_fbox &&
|
|
|
|
MCA_BTL_VADER_FBOX_FREE == fbox[0] && MCA_BTL_VADER_FBOX_FREE == fbox[MCA_BTL_VADER_FBOX_SIZE])) {
|
|
|
|
/* aggregate two fast boxes */
|
|
|
|
fbox[0] = MCA_BTL_VADER_FBOX_RESERVED;
|
|
|
|
ep->next_fbox_out = MCA_BTL_VADER_NEXT_FBOX(next_fbox + 1);
|
|
|
|
return fbox + 2;
|
2011-10-27 20:22:46 +00:00
|
|
|
}
|
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
return NULL;
|
2011-10-27 20:22:46 +00:00
|
|
|
}
|
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
static inline void mca_btl_vader_fbox_send (unsigned char * restrict fbox, unsigned char tag,
|
|
|
|
size_t size)
|
2011-10-27 20:22:46 +00:00
|
|
|
{
|
|
|
|
fbox[-1] = tag;
|
|
|
|
|
|
|
|
/* ensure data writes have completed before we mark the data as available */
|
|
|
|
opal_atomic_wmb ();
|
|
|
|
|
|
|
|
fbox[-2] = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int mca_btl_vader_fbox_sendi (struct mca_btl_base_endpoint_t *endpoint, char tag,
|
2013-07-11 20:54:12 +00:00
|
|
|
void * restrict header, const size_t header_size,
|
|
|
|
void * restrict payload, const size_t payload_size)
|
2011-10-27 20:22:46 +00:00
|
|
|
{
|
2013-07-11 20:54:12 +00:00
|
|
|
unsigned char * restrict fbox;
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-03-27 22:10:02 +00:00
|
|
|
fbox = mca_btl_vader_reserve_fbox(endpoint, header_size + payload_size);
|
2012-02-23 16:29:45 +00:00
|
|
|
if (OPAL_UNLIKELY(NULL == fbox)) {
|
2011-11-02 15:07:57 +00:00
|
|
|
return 0;
|
2011-10-27 20:22:46 +00:00
|
|
|
}
|
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
memmove (fbox, header, header_size);
|
2011-10-27 20:22:46 +00:00
|
|
|
if (OPAL_UNLIKELY(payload)) {
|
2011-11-02 15:07:57 +00:00
|
|
|
/* inline sends are typically just pml headers (due to MCA_BTL_FLAGS_SEND_INPLACE) */
|
2013-07-11 20:54:12 +00:00
|
|
|
memmove (fbox + header_size, payload, payload_size);
|
2011-10-27 20:22:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* mark the fbox as sent */
|
|
|
|
mca_btl_vader_fbox_send (fbox, tag, header_size + payload_size);
|
|
|
|
|
|
|
|
/* send complete */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void mca_btl_vader_check_fboxes (void)
|
|
|
|
{
|
2013-07-11 20:54:12 +00:00
|
|
|
mca_btl_vader_frag_t frag = {.base = {.des_dst = frag.segments, .des_dst_cnt = 1}};
|
|
|
|
const int num_smp_procs = MCA_BTL_VADER_NUM_LOCAL_PEERS + 1;
|
|
|
|
const mca_btl_active_message_callback_t *reg;
|
2013-03-27 22:10:02 +00:00
|
|
|
struct mca_btl_base_endpoint_t *endpoint;
|
2013-07-11 20:54:12 +00:00
|
|
|
unsigned char * restrict fbox;
|
2013-03-27 22:10:02 +00:00
|
|
|
int i, next_fbox;
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
for (i = 0, endpoint = mca_btl_vader_component.endpoints ; i < num_smp_procs ; ++i, ++endpoint) {
|
|
|
|
if (NULL == endpoint->fbox_in) {
|
2011-11-02 15:07:57 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-03-27 22:10:02 +00:00
|
|
|
next_fbox = endpoint->next_fbox_in;
|
|
|
|
fbox = (unsigned char *) MCA_BTL_VADER_FBOX_IN_PTR(endpoint, next_fbox);
|
|
|
|
|
2011-11-02 15:07:57 +00:00
|
|
|
/* process all fast-box messages */
|
2013-07-11 20:54:12 +00:00
|
|
|
while ((frag.segments[0].seg_len = fbox[0]) & 0x7f) {
|
|
|
|
const unsigned char tag = fbox[1];
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
opal_atomic_rmb ();
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2011-11-02 15:07:57 +00:00
|
|
|
reg = mca_btl_base_active_message_trigger + tag;
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2012-12-13 23:18:53 +00:00
|
|
|
frag.segments[0].seg_addr.pval = fbox + 2;
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2011-11-02 15:07:57 +00:00
|
|
|
reg->cbfunc(&mca_btl_vader.super, tag, &(frag.base), reg->cbdata);
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
if (fbox[0] > MCA_BTL_VADER_FBOX_MAX_SIZE) {
|
|
|
|
fbox[MCA_BTL_VADER_FBOX_SIZE] = MCA_BTL_VADER_FBOX_FREE;
|
|
|
|
++next_fbox;
|
|
|
|
}
|
2011-11-02 15:07:57 +00:00
|
|
|
fbox[0] = MCA_BTL_VADER_FBOX_FREE;
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-07-11 20:54:12 +00:00
|
|
|
next_fbox = MCA_BTL_VADER_NEXT_FBOX(next_fbox);
|
2013-03-27 22:10:02 +00:00
|
|
|
fbox = (unsigned char *) MCA_BTL_VADER_FBOX_IN_PTR(endpoint, next_fbox);
|
2011-11-02 15:07:57 +00:00
|
|
|
}
|
2011-10-27 20:22:46 +00:00
|
|
|
|
2013-03-27 22:10:02 +00:00
|
|
|
endpoint->next_fbox_in = next_fbox;
|
2011-10-27 20:22:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* !defined(MCA_BTL_VADER_FBOX_H) */
|
2013-07-11 20:54:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|