#ifndef UCT_MM_IFACE_H
#define UCT_MM_IFACE_H
#include "mm_md.h"
#include <uct/base/uct_iface.h>
#include <uct/sm/base/sm_iface.h>
#include <ucs/arch/cpu.h>
#include <ucs/debug/memtrack_int.h>
#include <ucs/datastruct/arbiter.h>
#include <ucs/sys/compiler.h>
#include <ucs/sys/sys.h>
#include <sys/shm.h>
#include <sys/un.h>
enum {
UCT_MM_FIFO_ELEM_FLAG_OWNER = UCS_BIT(0),
UCT_MM_FIFO_ELEM_FLAG_INLINE = UCS_BIT(1),
};
#define UCT_MM_FIFO_CTL_SIZE \
ucs_align_up(sizeof(uct_mm_fifo_ctl_t), UCS_SYS_CACHE_LINE_SIZE)
#define UCT_MM_GET_FIFO_SIZE(_iface) \
(UCT_MM_FIFO_CTL_SIZE + \
((_iface)->config.fifo_size * (_iface)->config.fifo_elem_size) + \
(UCS_SYS_CACHE_LINE_SIZE - 1))
#define UCT_MM_IFACE_GET_FIFO_ELEM(_iface, _fifo, _index) \
((uct_mm_fifo_element_t*) \
UCS_PTR_BYTE_OFFSET(_fifo, (_index) * (_iface)->config.fifo_elem_size))
#define uct_mm_iface_mapper_call(_iface, _func, ...) \
({ \
uct_mm_md_t *md = ucs_derived_of((_iface)->super.super.md, uct_mm_md_t); \
uct_mm_md_mapper_call(md, _func, ## __VA_ARGS__); \
})
#define uct_mm_iface_trace_am(_iface, _type, _flags, _am_id, _data, _length, \
_elem_sn) \
uct_iface_trace_am(&(_iface)->super.super, _type, _am_id, _data, _length, \
"%cX [%lu] %c%c", \
((_type) == UCT_AM_TRACE_TYPE_RECV) ? 'R' : \
((_type) == UCT_AM_TRACE_TYPE_SEND) ? 'T' : \
'?', \
(_elem_sn), \
((_flags) & UCT_MM_FIFO_ELEM_FLAG_OWNER) ? 'o' : '-', \
((_flags) & UCT_MM_FIFO_ELEM_FLAG_INLINE) ? 'i' : '-')
#define UCT_MM_IFACE_FIFO_MIN_POLL 1
#define UCT_MM_IFACE_FIFO_MAX_POLL 16
#define UCT_MM_IFACE_FIFO_AI_VALUE 1
#define UCT_MM_IFACE_FIFO_MD_FACTOR 2
#define UCT_MM_IFACE_FIFO_HEAD_EVENT_ARMED UCS_BIT(63)
typedef struct uct_mm_iface_config {
uct_sm_iface_config_t super;
size_t seg_size;
unsigned fifo_size;
size_t fifo_max_poll;
double release_fifo_factor;
ucs_ternary_auto_value_t hugetlb_mode;
unsigned fifo_elem_size;
int error_handling;
uct_iface_mpool_config_t mp;
} uct_mm_iface_config_t;
typedef struct uct_mm_iface_addr {
uct_mm_seg_id_t fifo_seg_id;
} UCS_S_PACKED uct_mm_iface_addr_t;
typedef struct uct_mm_fifo_ctl {
volatile uint64_t head;
socklen_t signal_addrlen;
struct sockaddr_un signal_sockaddr;
UCS_CACHELINE_PADDING(uint64_t,
socklen_t,
struct sockaddr_un);
volatile uint64_t tail;
pid_t pid;
} UCS_S_PACKED UCS_V_ALIGNED(UCS_SYS_CACHE_LINE_SIZE) uct_mm_fifo_ctl_t;
typedef struct uct_mm_desc_info {
uct_mm_seg_id_t seg_id;
unsigned seg_size;
unsigned offset;
} UCS_S_PACKED uct_mm_desc_info_t;
typedef struct uct_mm_fifo_element {
uint8_t flags;
uint8_t am_id;
uint16_t length;
uct_mm_desc_info_t desc;
void *desc_data;
} UCS_S_PACKED uct_mm_fifo_element_t;
typedef struct uct_mm_recv_desc {
uct_mm_desc_info_t info;
uct_recv_desc_t recv;
} uct_mm_recv_desc_t;
typedef struct uct_mm_iface {
uct_sm_iface_t super;
uct_allocated_memory_t recv_fifo_mem;
uct_mm_fifo_ctl_t *recv_fifo_ctl;
void *recv_fifo_elems;
uct_mm_fifo_element_t *read_index_elem;
uint64_t read_index;
uint8_t fifo_shift;
unsigned fifo_mask;
uint64_t fifo_release_factor_mask;
unsigned fifo_poll_count;
int fifo_prev_wnd_cons;
ucs_mpool_t recv_desc_mp;
uct_mm_recv_desc_t *last_recv_desc;
int signal_fd;
size_t rx_headroom;
ucs_arbiter_t arbiter;
uct_recv_desc_t release_desc;
struct {
unsigned fifo_size;
unsigned fifo_elem_size;
unsigned seg_size;
unsigned fifo_max_poll;
uint64_t extra_cap_flags;
} config;
} uct_mm_iface_t;
#define UCT_MM_TL_DEFINE(_name, _md_ops, _rkey_unpack, _rkey_release, \
_cfg_prefix, _cfg_table) \
\
UCT_MM_COMPONENT_DEFINE(uct_##_name##_component, _name, _md_ops, \
_rkey_unpack, _rkey_release, _cfg_prefix) \
\
UCT_TL_DEFINE(&(uct_##_name##_component).super, \
_name, \
uct_sm_base_query_tl_devices, \
uct_mm_iface_t, \
_cfg_prefix, \
_cfg_table, \
uct_mm_iface_config_t);
extern ucs_config_field_t uct_mm_iface_config_table[];
static UCS_F_ALWAYS_INLINE ucs_status_t
uct_mm_iface_invoke_am(uct_mm_iface_t *iface, uint8_t am_id, void *data,
unsigned length, unsigned flags)
{
ucs_status_t status;
void *desc;
status = uct_iface_invoke_am(&iface->super.super, am_id, data, length,
flags);
if (status == UCS_INPROGRESS) {
desc = (void *)((uintptr_t)data - iface->rx_headroom);
uct_recv_desc(desc) = &iface->release_desc;
}
return status;
}
void uct_mm_iface_set_fifo_ptrs(void *fifo_mem, uct_mm_fifo_ctl_t **fifo_ctl_p,
void **fifo_elems_p);
UCS_CLASS_DECLARE_NEW_FUNC(uct_mm_iface_t, uct_iface_t, uct_md_h, uct_worker_h,
const uct_iface_params_t*, const uct_iface_config_t*);
void uct_mm_iface_release_desc(uct_recv_desc_t *self, void *desc);
ucs_status_t uct_mm_flush();
#endif