libmemif: external region support

region 0: descriptors
region 1: buffers (external)

Change-Id: Ia728967817b4c78bc00f8eed44606d0c5bc386b0
Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
This commit is contained in:
Jakub Grajciar
2018-08-20 14:26:32 +02:00
committed by Damjan Marion
parent 43b0606301
commit 93a5dd1723
9 changed files with 1460 additions and 123 deletions

View File

@@ -78,7 +78,15 @@ icmpr_mt_SOURCES = examples/icmp_responder-mt/main.c \
icmpr_mt_LDADD = libmemif.la -lpthread
icmpr_mt_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/examples/icmp_responder
noinst_PROGRAMS = icmpr icmpr-epoll icmpr-mt
#
# ICMP responder external buffer example
#
icmpr_eb_SOURCES = examples/icmp_responder-eb/main.c\
examples/icmp_responder/icmp_proto.c
icmpr_eb_LDADD = libmemif.la -lpthread
icmpr_eb_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/examples/icmp_responder
noinst_PROGRAMS = icmpr icmpr-epoll icmpr-mt icmpr-eb
include_HEADERS = src/libmemif.h

View File

File diff suppressed because it is too large Load Diff

View File

@@ -86,6 +86,8 @@
#define MAX_MEMIF_BUFS 256
#define MAX_CONNS 50
#define ICMPR_HEADROOM 64
int epfd;
int out_fd;
uint8_t enable_log;
@@ -282,7 +284,7 @@ int
on_connect (memif_conn_handle_t conn, void *private_ctx)
{
INFO ("memif connected!");
memif_refill_queue (conn, 0, -1, 0);
memif_refill_queue (conn, 0, -1, ICMPR_HEADROOM);
enable_log = 1;
return 0;
}
@@ -406,13 +408,12 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
tx--;
}
err = memif_refill_queue (c->conn, qid, rx, 0);
err = memif_refill_queue (c->conn, qid, rx, ICMPR_HEADROOM);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
rx -= rx;
DBG ("freed %d buffers. %u/%u alloc/free buffers",
rx, rx, MAX_MEMIF_BUFS - rx);
DBG ("%u/%u alloc/free buffers", rx, MAX_MEMIF_BUFS - rx);
err = memif_tx_burst (c->conn, qid, c->tx_bufs, j, &tx);
if (err != MEMIF_ERR_SUCCESS)
@@ -428,7 +429,7 @@ on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
return 0;
error:
err = memif_refill_queue (c->conn, qid, rx, 0);
err = memif_refill_queue (c->conn, qid, rx, ICMPR_HEADROOM);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
@@ -514,7 +515,7 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
}
/* mark memif buffers and shared memory buffers as free */
/* free processed buffers */
err = memif_refill_queue (c->conn, qid, j, 0);
err = memif_refill_queue (c->conn, qid, j, ICMPR_HEADROOM);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
rx -= j;
@@ -540,7 +541,7 @@ on_interrupt0 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
return 0;
error:
err = memif_refill_queue (c->conn, qid, rx, 0);
err = memif_refill_queue (c->conn, qid, rx, ICMPR_HEADROOM);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
@@ -597,7 +598,7 @@ on_interrupt1 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
}
}
err = memif_refill_queue (c->conn, qid, rx, 0);
err = memif_refill_queue (c->conn, qid, rx, ICMPR_HEADROOM);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
@@ -609,7 +610,7 @@ on_interrupt1 (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
return 0;
error:
err = memif_refill_queue (c->conn, qid, rx, 0);
err = memif_refill_queue (c->conn, qid, rx, ICMPR_HEADROOM);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_buffer_free: %s", memif_strerror (err));
c->rx_buf_num -= rx;
@@ -992,6 +993,7 @@ icmpr_send_proc (void *data)
count -= tx;
}
timespec_get (&end, TIME_UTC);
printf ("\n\n");
INFO ("Pakcet sequence finished!");
INFO ("Seq len: %u", seq);
uint64_t t1 = end.tv_sec - start.tv_sec;
@@ -1297,7 +1299,7 @@ main ()
/* if valid callback is passed as argument, fd event polling will be done by user
all file descriptors and events will be passed to user in this callback */
/* if callback is set to NULL libmemif will handle fd event polling */
err = memif_init (control_fd_update, APP_NAME, NULL, NULL);
err = memif_init (control_fd_update, APP_NAME, NULL, NULL, NULL);
if (err != MEMIF_ERR_SUCCESS)
{
INFO ("memif_init: %s", memif_strerror (err));

View File

@@ -894,7 +894,7 @@ main ()
/* if valid callback is passed as argument, fd event polling will be done by user
all file descriptors and events will be passed to user in this callback */
/* if callback is set to NULL libmemif will handle fd event polling */
err = memif_init (control_fd_update, APP_NAME, NULL, NULL);
err = memif_init (control_fd_update, APP_NAME, NULL, NULL, NULL);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_init: %s", memif_strerror (err));

View File

@@ -395,7 +395,7 @@ main (int argc, char *argv[])
/* if valid callback is passed as argument, fd event polling will be done by user
all file descriptors and events will be passed to user in this callback */
/* if callback is set to NULL libmemif will handle fd event polling */
err = memif_init (NULL, APP_NAME, NULL, NULL);
err = memif_init (NULL, APP_NAME, NULL, NULL, NULL);
if (err != MEMIF_ERR_SUCCESS)
INFO ("memif_init: %s", memif_strerror (err));

View File

@@ -106,6 +106,15 @@ typedef void *memif_conn_handle_t;
*/
typedef void *(memif_alloc_t) (size_t size);
/** \brief Memif realloc
@param ptr - pointer to memory block
@param size - requested allocation size
custom memory reallocation
*/
typedef void *(memif_realloc_t) (void *ptr, size_t size);
/** \brief Memif allocator free
@param size - requested allocation size
@@ -148,6 +157,68 @@ typedef int (memif_connection_update_t) (memif_conn_handle_t conn,
*/
typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
uint16_t qid);
/** @} */
/**
* @defgroup EXTERNAL_REGION External region APIs
* @ingroup libmemif
*
* @{
*/
/** \brief Get external buffer offset (optional)
@param private_ctx - private context
Find unallocated external buffer and return its offset.
*/
typedef uint32_t (memif_get_external_buffer_offset_t) (void *private_ctx);
/** \brief Add external region
@param[out] addr - region address
@param size - requested region size
@param fd[out] - file descriptor
@param private_ctx - private context
Called by slave. Add external region created by client.
*/
typedef int (memif_add_external_region_t) (void * *addr, uint32_t size,
int *fd, void *private_ctx);
/** \brief Get external region address
@param size - requested region size
@param fd - file descriptor
@param private_ctx - private context
Called by master. Get region address from client.
\return region address
*/
typedef void *(memif_get_external_region_addr_t) (uint32_t size, int fd,
void *private_ctx);
/** \brief Delete external region
@param addr - region address
@param size - region size
@param fd - file descriptor
@param private_ctx - private context
Delete external region.
*/
typedef int (memif_del_external_region_t) (void *addr, uint32_t size, int fd,
void *private_ctx);
/** \brief Register external region
@param ar - add external region callback
@param gr - get external region addr callback
@param dr - delete external region callback
@param go - get external buffer offset callback (optional)
*/
void memif_register_external_region (memif_add_external_region_t * ar,
memif_get_external_region_addr_t * gr,
memif_del_external_region_t * dr,
memif_get_external_buffer_offset_t * go);
/** @} */
/**
@@ -230,6 +301,7 @@ typedef struct
*/
/** \brief Memif queue details
@param region - region index
@param qid - queue id
@param ring_size - size of ring buffer in sharem memory
@param flags - ring flags
@@ -239,6 +311,7 @@ typedef struct
*/
typedef struct
{
uint8_t region;
uint8_t qid;
uint32_t ring_size;
/** if set queue is in polling mode, else in interrupt mode */
@@ -249,6 +322,22 @@ typedef struct
uint16_t buffer_size;
} memif_queue_details_t;
/** \brief Memif region details
@param index - region index
@param addr - region address
@param size - region size
@param fd - file descriptor
@param is_external - if not zero then region is defined by client
*/
typedef struct
{
uint8_t index;
void *addr;
uint32_t size;
int fd;
uint8_t is_external;
} memif_region_details_t;
/** \brief Memif details
@param if_name - interface name
@param inst_name - application name
@@ -258,7 +347,9 @@ typedef struct
@param secret - secret
@param role - 0 = master, 1 = slave
@param mode - 0 = ethernet, 1 = ip , 2 = punt/inject
@param socket_filename = socket filename
@param socket_filename - socket filename
@param regions_num - number of regions
@param regions - struct containing region details
@param rx_queues_num - number of receive queues
@param tx_queues_num - number of transmit queues
@param rx_queues - struct containing receive queue details
@@ -277,6 +368,8 @@ typedef struct
uint8_t role; /* 0 = master, 1 = slave */
uint8_t mode; /* 0 = ethernet, 1 = ip, 2 = punt/inject */
uint8_t *socket_filename;
uint8_t regions_num;
memif_region_details_t *regions;
uint8_t rx_queues_num;
uint8_t tx_queues_num;
memif_queue_details_t *rx_queues;
@@ -343,6 +436,7 @@ int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
@param on_control_fd_update - if control fd updates inform user to watch new fd
@param app_name - application name (will be truncated to 32 chars)
@param memif_alloc - cutom memory allocator, NULL = default
@param memif_realloc - custom memory reallocation, NULL = default
@param memif_free - custom memory free, NULL = default
if param on_control_fd_update is set to NULL,
@@ -359,7 +453,7 @@ int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
*/
int memif_init (memif_control_fd_update_t * on_control_fd_update,
char *app_name, memif_alloc_t * memif_alloc,
memif_free_t * memif_free);
memif_realloc_t * memif_realloc, memif_free_t * memif_free);
/** \brief Memif cleanup

View File

File diff suppressed because it is too large Load Diff

View File

@@ -67,10 +67,11 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
typedef struct
{
void *shm;
void *addr;
uint32_t region_size;
uint32_t buffer_offset;
int fd;
uint8_t is_external;
} memif_region_t;
typedef struct
@@ -133,8 +134,11 @@ typedef struct memif_connection
uint8_t remote_name[MEMIF_NAME_LEN];
uint8_t remote_disconnect_string[96];
uint8_t regions_num;
memif_region_t *regions;
uint8_t rx_queues_num;
uint8_t tx_queues_num;
memif_queue_t *rx_queues;
memif_queue_t *tx_queues;
@@ -165,7 +169,13 @@ typedef struct
uint16_t disconn_slaves;
uint8_t app_name[MEMIF_NAME_LEN];
memif_add_external_region_t *add_external_region;
memif_get_external_region_addr_t *get_external_region_addr;
memif_del_external_region_t *del_external_region;
memif_get_external_buffer_offset_t *get_external_buffer_offset;
memif_alloc_t *alloc;
memif_realloc_t *realloc;
memif_free_t *free;
uint16_t control_list_len;
@@ -226,7 +236,7 @@ static inline void *
memif_get_buffer (memif_connection_t * conn, memif_ring_t * ring,
uint16_t index)
{
return (conn->regions[ring->desc[index].region].shm +
return (conn->regions[ring->desc[index].region].addr +
ring->desc[index].offset);
}

View File

@@ -112,7 +112,8 @@ memif_msg_send_hello (int fd)
h->max_region = MEMIF_MAX_REGION;
h->max_log2_ring_size = MEMIF_MAX_LOG2_RING_SIZE;
strncpy ((char *) h->name, (char *) lm->app_name, strlen ((char *) lm->app_name));
strncpy ((char *) h->name, (char *) lm->app_name,
strlen ((char *) lm->app_name));
/* msg hello is not enqueued but sent directly,
because it is the first msg to be sent */
@@ -141,7 +142,7 @@ memif_msg_enq_init (memif_connection_t * c)
strncpy ((char *) i->name, (char *) lm->app_name,
strlen ((char *) lm->app_name));
if (strlen((char *) c->args.secret) > 0)
if (strlen ((char *) c->args.secret) > 0)
strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
e->next = NULL;
@@ -166,7 +167,6 @@ static_fn int
memif_msg_enq_add_region (memif_connection_t * c, uint8_t region_index)
{
libmemif_main_t *lm = &libmemif_main;
/* maybe check if region is valid? */
memif_region_t *mr = &c->regions[region_index];
memif_msg_queue_elt_t *e =
@@ -424,10 +424,10 @@ memif_msg_receive_init (memif_socket_t * ms, int fd, memif_msg_t * msg)
strncpy ((char *) c->remote_name, (char *) i->name,
strlen ((char *) i->name));
if (strlen((char *) c->args.secret) > 0)
if (strlen ((char *) c->args.secret) > 0)
{
int r;
if (strlen((char *) i->secret) > 0)
if (strlen ((char *) i->secret) > 0)
{
if (strlen ((char *) c->args.secret) != strlen ((char *) i->secret))
{
@@ -484,6 +484,8 @@ static_fn int
memif_msg_receive_add_region (memif_connection_t * c, memif_msg_t * msg,
int fd)
{
libmemif_main_t *lm = &libmemif_main;
memif_msg_add_region_t *ar = &msg->add_region;
memif_region_t *mr;
if (fd < 0)
@@ -493,14 +495,19 @@ memif_msg_receive_add_region (memif_connection_t * c, memif_msg_t * msg,
return MEMIF_ERR_MAXREG;
mr =
(memif_region_t *) realloc (c->regions,
sizeof (memif_region_t) * (ar->index + 1));
(memif_region_t *) lm->realloc (c->regions,
sizeof (memif_region_t) *
(++c->regions_num));
if (mr == NULL)
return memif_syscall_error_handler (errno);
memset (mr + ar->index, 0, sizeof (memif_region_t));
c->regions = mr;
c->regions[ar->index].fd = fd;
c->regions[ar->index].region_size = ar->size;
c->regions[ar->index].shm = NULL;
c->regions[ar->index].addr = NULL;
if (lm->get_external_region_addr)
c->regions[ar->index].is_external = 1;
return MEMIF_ERR_SUCCESS; /* 0 */
}
@@ -510,6 +517,8 @@ memif_msg_receive_add_region (memif_connection_t * c, memif_msg_t * msg,
static_fn int
memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
{
libmemif_main_t *lm = &libmemif_main;
memif_msg_add_ring_t *ar = &msg->add_ring;
memif_queue_t *mq;
@@ -528,8 +537,9 @@ memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
return MEMIF_ERR_MAXRING;
mq =
(memif_queue_t *) realloc (c->rx_queues,
sizeof (memif_queue_t) * (ar->index + 1));
(memif_queue_t *) lm->realloc (c->rx_queues,
sizeof (memif_queue_t) *
(++c->rx_queues_num));
memset (mq + ar->index, 0, sizeof (memif_queue_t));
if (mq == NULL)
return memif_syscall_error_handler (errno);
@@ -548,8 +558,9 @@ memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
return MEMIF_ERR_MAXRING;
mq =
(memif_queue_t *) realloc (c->tx_queues,
sizeof (memif_queue_t) * (ar->index + 1));
(memif_queue_t *) lm->realloc (c->tx_queues,
sizeof (memif_queue_t) *
(++c->tx_queues_num));
memset (mq + ar->index, 0, sizeof (memif_queue_t));
if (mq == NULL)
return memif_syscall_error_handler (errno);
@@ -718,8 +729,11 @@ memif_msg_receive (int ifd)
return err;
if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
return err;
if ((err = memif_msg_enq_add_region (c, 0)) != MEMIF_ERR_SUCCESS)
return err;
for (i = 0; i < c->regions_num; i++)
{
if ((err = memif_msg_enq_add_region (c, i)) != MEMIF_ERR_SUCCESS)
return err;
}
for (i = 0; i < c->run_args.num_s2m_rings; i++)
{
if ((err =