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:

committed by
Damjan Marion

parent
43b0606301
commit
93a5dd1723
@@ -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
|
||||
|
||||
|
1073
extras/libmemif/examples/icmp_responder-eb/main.c
Normal file
1073
extras/libmemif/examples/icmp_responder-eb/main.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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));
|
||||
|
@@ -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));
|
||||
|
||||
|
@@ -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));
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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 =
|
||||
|
Reference in New Issue
Block a user