Program Listing for File memory_registration.c
↰ Return to documentation for file (memory_registration.c
)
#include "netio/netio.h"
#include <string.h>
#include <stdio.h>
#include "log.h"
#if defined DEBUG || defined DEBUG_MR
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#define log_dbg(...) log_log(LOG_DEBUG, __FILENAME__, __LINE__, __VA_ARGS__)
#define log_trc(...) log_log(LOG_TRACE, __FILENAME__, __LINE__, __VA_ARGS__)
#else
#define log_dbg(...)
#define log_trc(...)
#endif
static void
init_bufferstack(struct netio_buffer_stack* stack, unsigned num, size_t bufsize)
{
stack->buffers = malloc(num*sizeof(struct netio_buffer*));
stack->buffer_addresses = malloc(num*sizeof(struct netio_buffer*));
stack->num_buffers = num;
stack->available_buffers = num;
for(unsigned int i=0; i<num; i++) {
stack->buffers[i] = malloc(sizeof(struct netio_buffer));
stack->buffers[i]->data = malloc(bufsize);
stack->buffers[i]->size = bufsize;
stack->buffers[i]->mr = NULL;
stack->buffer_addresses[i] = stack->buffers[i];
}
}
void netio_register_recv_buffer(struct netio_recv_socket* socket, struct netio_buffer* buf, uint64_t flags)
{
if (socket->tcp_fi_mode != NETIO_MODE_LIBFABRIC) {
return;
}
log_trc("registering recv buffer number: %d", socket->reg_mr);
uint64_t access = FI_RECV;
int ret = 0;
if((ret = fi_mr_reg(socket->domain, buf->data, buf->size, access, 0, socket->req_key++, 0, &buf->mr, NULL)))
{
log_fatal("Failed to register recv buffer (key %lu) failed. Error %d: %s",socket->req_key, ret, fi_strerror(-ret));
//exit(2);
}
if(ret==0){
if (socket->reg_mr >= NETIO_DOMAIN_MAX_MR){
log_fatal("Trying to register recv buffer number %u. MR array size %lu.", socket->reg_mr, NETIO_DOMAIN_MAX_MR);
exit(1);
}
socket->mr[socket->reg_mr]=&buf->mr->fid;
socket->reg_mr+=1;
}
}
void netio_register_send_buffer(struct netio_send_socket* socket, struct netio_buffer* buf, uint64_t flags)
{
if (socket->tcp_fi_mode != NETIO_MODE_LIBFABRIC) {
return;
}
uint64_t access = FI_SEND;
int ret = 0;
if((ret = fi_mr_reg(socket->domain->domain, buf->data, buf->size, access, 0, socket->domain->req_key++, 0, &buf->mr, NULL)))
{
log_fatal("Failed to register send buffer failed. Error %d: %s.", ret, fi_strerror(-ret));
exit(2);
}
if(ret==0){
if (socket->domain->reg_mr >= NETIO_DOMAIN_MAX_MR){
log_fatal("Trying to register send buffer number %u. MR array size %lu.", socket->domain->reg_mr, NETIO_DOMAIN_MAX_MR);
exit(1);
}
socket->domain->mr[socket->domain->reg_mr]=&buf->mr->fid;
socket->domain->reg_mr+=1;
}
}
void
netio_bufferstack_send_init(struct netio_buffer_stack* stack, struct netio_send_socket* socket, size_t num, size_t bufsize, uint64_t flags)
{
log_dbg("Initializing memory: %d pages", num);
init_bufferstack(stack, num, bufsize);
if (socket->tcp_fi_mode==NETIO_MODE_LIBFABRIC) {
socket->domain->reg_mr=0;
for(unsigned i=0; i<num; i++) {
netio_register_send_buffer(socket, stack->buffers[i], flags);
}
}
}
void
netio_bufferstack_close(struct netio_buffer_stack* stack, size_t num)
{
log_dbg("Freeing memory: %d pages", num);
for(unsigned int i=0; i < num; i++) {
if(stack->buffers == NULL){log_warn("Buffer already released."); return;}
free(stack->buffer_addresses[i]->data);
free(stack->buffer_addresses[i]);
}
free(stack->buffers);
free(stack->buffer_addresses);
stack->buffers = NULL;
}
int
netio_bufferstack_pop(struct netio_buffer_stack* stack, struct netio_buffer** buffer)
{
log_trc("pop: available %lu", stack->available_buffers);
if(stack->available_buffers > 0) {
stack->available_buffers--;
*buffer = stack->buffers[stack->available_buffers];
return 0;
} else {
return 1;
}
}
int
netio_bufferstack_push(struct netio_buffer_stack* stack, struct netio_buffer* buffer)
{
log_trc("push: available %lu", stack->available_buffers);
if(stack->available_buffers < stack->num_buffers) {
stack->buffers[stack->available_buffers] = buffer;
stack->available_buffers++;
return 0;
} else {
return 1;
}
}