aboutsummaryrefslogtreecommitdiffstats
path: root/extras/libmemif/src
diff options
context:
space:
mode:
authorJakub Grajciar <jgrajcia@cisco.com>2018-03-26 11:26:34 +0200
committerDamjan Marion <dmarion.lists@gmail.com>2018-03-26 12:01:49 +0000
commitecfa2aaa631933f5c77858ae3e5e15a76619dd77 (patch)
treeaa6dc67e3c1153ed7fe316a4798429a27c3544a5 /extras/libmemif/src
parentb4ff07a2f843207b6d024e1ed8a31fa37324fe07 (diff)
libmemif: version 2
Change-Id: Ia2532695aa9199d2a7b684aebef43df0b8235531 Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
Diffstat (limited to 'extras/libmemif/src')
-rw-r--r--extras/libmemif/src/libmemif.h69
-rw-r--r--extras/libmemif/src/main.c850
-rw-r--r--extras/libmemif/src/memif.h14
-rw-r--r--extras/libmemif/src/memif_private.h47
-rw-r--r--extras/libmemif/src/socket.c40
5 files changed, 414 insertions, 606 deletions
diff --git a/extras/libmemif/src/libmemif.h b/extras/libmemif/src/libmemif.h
index a14a1025a54..14c450338ce 100644
--- a/extras/libmemif/src/libmemif.h
+++ b/extras/libmemif/src/libmemif.h
@@ -23,14 +23,12 @@
#define _LIBMEMIF_H_
/** Libmemif version. */
-#define LIBMEMIF_VERSION "1.0"
+#define LIBMEMIF_VERSION "2.0"
/** Default name of application using libmemif. */
#define MEMIF_DEFAULT_APP_NAME "libmemif-app"
#include <inttypes.h>
-#include <memif.h>
-
/*! Error codes */
typedef enum
{
@@ -95,10 +93,25 @@ typedef enum
#define MEMIF_FD_EVENT_MOD (1 << 4)
/** @} */
-/** *brief Memif connection handle
+/** \brief Memif connection handle
pointer of type void, pointing to internal structure
*/
typedef void *memif_conn_handle_t;
+
+/** \brief Memif allocator alloc
+ @param size - requested allocation size
+
+ custom memory allocator: alloc function template
+*/
+typedef void *(memif_alloc_t) (size_t size);
+
+/** \brief Memif allocator free
+ @param size - requested allocation size
+
+ custom memory allocator: free function template
+*/
+typedef void (memif_free_t) (void *ptr);
+
/**
* @defgroup CALLBACKS Callback functions definitions
* @ingroup libmemif
@@ -143,6 +156,15 @@ typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
* @{
*/
+#ifndef _MEMIF_H_
+typedef enum
+{
+ MEMIF_INTERFACE_MODE_ETHERNET = 0,
+ MEMIF_INTERFACE_MODE_IP = 1,
+ MEMIF_INTERFACE_MODE_PUNT_INJECT = 2,
+} memif_interface_mode_t;
+#endif /* _MEMIF_H_ */
+
/** \brief Memif connection arguments
@param socket_filename - socket filename
@param secret - otional parameter used as interface autenthication
@@ -153,7 +175,6 @@ typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
@param is_master - 0 == master, 1 == slave
@param interface_id - id used to identify peer connection
@param interface_name - interface name
- @param instance_name - application name
@param mode - 0 == ethernet, 1 == ip , 2 == punt/inject
*/
typedef struct
@@ -164,12 +185,11 @@ typedef struct
uint8_t num_s2m_rings; /*!< default = 1 */
uint8_t num_m2s_rings; /*!< default = 1 */
uint16_t buffer_size; /*!< default = 2048 */
- memif_log2_ring_size_t log2_ring_size; /*!< default = 10 (1024) */
+ uint8_t log2_ring_size; /*!< default = 10 (1024) */
uint8_t is_master;
- memif_interface_id_t interface_id;
+ uint32_t interface_id;
uint8_t interface_name[32];
- uint8_t instance_name[32]; /*!< deprecated, will be removed in 2.0 */
memif_interface_mode_t mode:8;
} memif_conn_args_t;
@@ -182,15 +202,16 @@ typedef enum
/** \brief Memif buffer
@param desc_index - ring descriptor index
- @param buffer_len - shared meory buffer length
- @param data_len - data length
+ @param len - buffer length
+ @param flags - memif buffer flags
@param data - pointer to shared memory data
*/
typedef struct
{
uint16_t desc_index;
- uint32_t buffer_len;
- uint32_t data_len;
+ uint32_t len;
+#define MEMIF_BUFFER_FLAG_NEXT (1 << 0)
+ uint8_t flags;
void *data;
} memif_buffer_t;
/** @} */
@@ -266,6 +287,12 @@ typedef struct
* @{
*/
+/** \brief Memif get version
+
+ \return ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
+*/
+uint16_t memif_get_version ();
+
/** \biref Memif get queue event file descriptor
@param conn - memif connection handle
@param qid - queue id
@@ -309,6 +336,8 @@ int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
/** \brief Memif initialization
@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_free - custom memory free, NULL = default
if param on_control_fd_update is set to NULL,
libmemif will handle file descriptor event polling
@@ -323,7 +352,8 @@ int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
\return memif_err_t
*/
int memif_init (memif_control_fd_update_t * on_control_fd_update,
- char *app_name);
+ char *app_name, memif_alloc_t * memif_alloc,
+ memif_free_t * memif_free);
/** \brief Memif cleanup
@@ -398,7 +428,7 @@ int memif_delete (memif_conn_handle_t * conn);
@param bufs - memif buffers
@param count - number of memif buffers to allocate
@param count_out - returns number of allocated buffers
- @param size - minimal buffer size, 0 = standard buffer size
+ @param size - buffer size, may return chained buffers if size > buffer_size
\return memif_err_t
*/
@@ -406,18 +436,15 @@ int memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
memif_buffer_t * bufs, uint16_t count,
uint16_t * count_out, uint16_t size);
-/** \brief Memif buffer free
+/** \brief Memif refill ring
@param conn - memif conenction handle
@param qid - number indentifying queue
- @param bufs - memif buffers
- @param count - number of memif buffers to free
- @param count_out - returns number of freed buffers
+ @param count - number of buffers to be placed on ring
\return memif_err_t
*/
-int memif_buffer_free (memif_conn_handle_t conn, uint16_t qid,
- memif_buffer_t * bufs, uint16_t count,
- uint16_t * count_out);
+int memif_refill_queue (memif_conn_handle_t conn, uint16_t qid,
+ uint16_t count);
/** \brief Memif transmit buffer burst
@param conn - memif conenction handle
diff --git a/extras/libmemif/src/main.c b/extras/libmemif/src/main.c
index cb24083c8e3..f83f71064e6 100644
--- a/extras/libmemif/src/main.c
+++ b/extras/libmemif/src/main.c
@@ -166,6 +166,12 @@ memif_strerror (int err_code)
return memif_buf;
}
+uint16_t
+memif_get_version ()
+{
+ return MEMIF_VERSION;
+}
+
#define DBG_TX_BUF (0)
#define DBG_RX_BUF (1)
@@ -191,7 +197,7 @@ print_bytes (void *data, uint16_t len, uint8_t q)
int
memif_syscall_error_handler (int err_code)
{
- DBG_UNIX ("%s", strerror (err_code));
+ DBG ("%s", strerror (err_code));
if (err_code == 0)
return MEMIF_ERR_SUCCESS;
@@ -401,18 +407,45 @@ memif_control_fd_update_register (memif_control_fd_update_t * cb)
lm->control_fd_update = cb;
}
+static void
+memif_alloc_register (memif_alloc_t * ma)
+{
+ libmemif_main_t *lm = &libmemif_main;
+ lm->alloc = ma;
+}
+
+static void
+memif_free_register (memif_free_t * mf)
+{
+ libmemif_main_t *lm = &libmemif_main;
+ lm->free = mf;
+}
+
int
-memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
+memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
+ memif_alloc_t * memif_alloc, memif_free_t * memif_free)
{
int err = MEMIF_ERR_SUCCESS; /* 0 */
libmemif_main_t *lm = &libmemif_main;
memset (lm, 0, sizeof (libmemif_main_t));
- if (app_name)
+ if (memif_alloc != NULL)
{
- uint8_t len = (strlen (app_name) < MEMIF_NAME_LEN)
- ? MEMIF_NAME_LEN : strlen (app_name);
- strncpy ((char *) lm->app_name, app_name, strlen (app_name));
+ memif_alloc_register (memif_alloc);
+ }
+ else
+ memif_alloc_register (malloc);
+
+ if (memif_free != NULL)
+ memif_free_register (memif_free);
+ else
+ memif_free_register (free);
+
+ if (app_name != NULL)
+ {
+ uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
+ ? strlen (app_name) : MEMIF_NAME_LEN;
+ strncpy ((char *) lm->app_name, app_name, len);
}
else
{
@@ -443,13 +476,33 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
lm->pending_list_len = 1;
lm->control_list =
- malloc (sizeof (memif_list_elt_t) * lm->control_list_len);
+ lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
+ if (lm->control_list == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
lm->interrupt_list =
- malloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
+ lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
+ if (lm->interrupt_list == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
lm->listener_list =
- malloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
+ lm->alloc (sizeof (memif_list_elt_t) * lm->listener_list_len);
+ if (lm->listener_list == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
lm->pending_list =
- malloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
+ lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
+ if (lm->pending_list == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
int i;
for (i = 0; i < lm->control_list_len; i++)
@@ -478,9 +531,8 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
if (lm->timerfd < 0)
{
- err = errno;
- DBG ("timerfd: %s", strerror (err));
- return memif_syscall_error_handler (err);
+ err = memif_syscall_error_handler (errno);
+ goto error;
}
lm->arm.it_value.tv_sec = 2;
@@ -491,10 +543,15 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name)
if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
{
DBG ("callback type memif_control_fd_update_t error!");
- return MEMIF_ERR_CB_FDUPDATE;
+ err = MEMIF_ERR_CB_FDUPDATE;
+ goto error;
}
- return 0;
+ return err;
+
+error:
+ memif_cleanup ();
+ return err;
}
static inline memif_ring_t *
@@ -520,8 +577,8 @@ memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
if (conn == NULL)
return MEMIF_ERR_NOCONN;
uint8_t num =
- (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
- run_args.num_m2s_rings;
+ (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->run_args.
+ num_m2s_rings;
if (qid >= num)
return MEMIF_ERR_QID;
@@ -536,6 +593,7 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
memif_connection_update_t * on_disconnect,
memif_interrupt_t * on_interrupt, void *private_ctx)
{
+ libmemif_main_t *lm = &libmemif_main;
int err, i, index, sockfd = -1;
memif_list_elt_t list_elt;
memif_connection_t *conn = (memif_connection_t *) * c;
@@ -544,16 +602,14 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
DBG ("This handle already points to existing memif.");
return MEMIF_ERR_CONN;
}
- conn = (memif_connection_t *) malloc (sizeof (memif_connection_t));
+ conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
if (conn == NULL)
{
- err = memif_syscall_error_handler (errno);
+ err = MEMIF_ERR_NOMEM;
goto error;
}
memset (conn, 0, sizeof (memif_connection_t));
- libmemif_main_t *lm = &libmemif_main;
-
conn->args.interface_id = args->interface_id;
if (args->log2_ring_size == 0)
@@ -591,13 +647,14 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
l);
- l = strlen ((char *) args->instance_name);
- strncpy ((char *) conn->args.instance_name, (char *) args->instance_name,
- l);
-
/* allocate and initialize socket_filename so it can be copyed to sun_path
without memory leaks */
- conn->args.socket_filename = malloc (sizeof (char *) * 108);
+ conn->args.socket_filename = lm->alloc (sizeof (char *) * 108);
+ if (conn->args.socket_filename == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
memset (conn->args.socket_filename, 0, 108 * sizeof (char *));
if (args->socket_filename)
@@ -668,10 +725,20 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
return memif_syscall_error_handler (errno);
}
DBG ("creating socket file");
- ms = malloc (sizeof (memif_socket_t));
+ ms = lm->alloc (sizeof (memif_socket_t));
+ if (ms == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
ms->filename =
- malloc (strlen ((char *) conn->args.socket_filename) +
- sizeof (char));
+ lm->alloc (strlen ((char *) conn->args.socket_filename) +
+ sizeof (char));
+ if (ms->filename == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
memset (ms->filename, 0,
strlen ((char *) conn->args.socket_filename) +
sizeof (char));
@@ -680,7 +747,13 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
strlen ((char *) conn->args.socket_filename));
ms->interface_list_len = 1;
ms->interface_list =
- malloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
+ lm->alloc (sizeof (memif_list_elt_t) *
+ ms->interface_list_len);
+ if (ms->interface_list == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
ms->interface_list[0].key = -1;
ms->interface_list[0].data_struct = NULL;
struct sockaddr_un un = { 0 };
@@ -772,9 +845,9 @@ error:
close (sockfd);
sockfd = -1;
if (conn->args.socket_filename)
- free (conn->args.socket_filename);
+ lm->free (conn->args.socket_filename);
if (conn != NULL)
- free (conn);
+ lm->free (conn);
*c = conn = NULL;
return err;
}
@@ -855,20 +928,21 @@ memif_control_fd_handler (int fd, uint8_t events)
if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
{
num =
- (((memif_connection_t *) e->data_struct)->
- args.is_master) ? ((memif_connection_t *) e->
- data_struct)->run_args.
- num_s2m_rings : ((memif_connection_t *) e->data_struct)->
- run_args.num_m2s_rings;
+ (((memif_connection_t *) e->data_struct)->args.
+ is_master) ? ((memif_connection_t *) e->data_struct)->
+ run_args.num_s2m_rings : ((memif_connection_t *) e->
+ data_struct)->run_args.
+ num_m2s_rings;
for (i = 0; i < num; i++)
{
- if (((memif_connection_t *) e->data_struct)->
- rx_queues[i].int_fd == fd)
+ if (((memif_connection_t *) e->data_struct)->rx_queues[i].
+ int_fd == fd)
{
- ((memif_connection_t *) e->data_struct)->
- on_interrupt ((void *) e->data_struct,
- ((memif_connection_t *) e->
- data_struct)->private_ctx, i);
+ ((memif_connection_t *) e->
+ data_struct)->on_interrupt ((void *) e->data_struct,
+ ((memif_connection_t *)
+ e->data_struct)->
+ private_ctx, i);
return MEMIF_ERR_SUCCESS;
}
}
@@ -895,24 +969,24 @@ memif_control_fd_handler (int fd, uint8_t events)
if (events & MEMIF_FD_EVENT_READ)
{
err =
- ((memif_connection_t *) e->data_struct)->
- read_fn (e->data_struct);
+ ((memif_connection_t *) e->data_struct)->read_fn (e->
+ data_struct);
if (err != MEMIF_ERR_SUCCESS)
return err;
}
if (events & MEMIF_FD_EVENT_WRITE)
{
err =
- ((memif_connection_t *) e->data_struct)->
- write_fn (e->data_struct);
+ ((memif_connection_t *) e->data_struct)->write_fn (e->
+ data_struct);
if (err != MEMIF_ERR_SUCCESS)
return err;
}
if (events & MEMIF_FD_EVENT_ERROR)
{
err =
- ((memif_connection_t *) e->data_struct)->
- error_fn (e->data_struct);
+ ((memif_connection_t *) e->data_struct)->error_fn (e->
+ data_struct);
if (err != MEMIF_ERR_SUCCESS)
return err;
}
@@ -985,12 +1059,12 @@ memif_cancel_poll_event ()
}
static void
-memif_msg_queue_free (memif_msg_queue_elt_t ** e)
+memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
{
if (*e == NULL)
return;
- memif_msg_queue_free (&(*e)->next);
- free (*e);
+ memif_msg_queue_free (lm, &(*e)->next);
+ lm->free (*e);
*e = NULL;
return;
}
@@ -1029,8 +1103,8 @@ memif_disconnect_internal (memif_connection_t * c)
if (c->tx_queues != NULL)
{
num =
- (c->args.is_master) ? c->run_args.num_m2s_rings : c->
- run_args.num_s2m_rings;
+ (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+ num_s2m_rings;
for (i = 0; i < num; i++)
{
mq = &c->tx_queues[i];
@@ -1043,15 +1117,15 @@ memif_disconnect_internal (memif_connection_t * c)
mq->int_fd = -1;
}
}
- free (c->tx_queues);
+ lm->free (c->tx_queues);
c->tx_queues = NULL;
}
if (c->rx_queues != NULL)
{
num =
- (c->args.is_master) ? c->run_args.num_s2m_rings : c->
- run_args.num_m2s_rings;
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+ num_m2s_rings;
for (i = 0; i < num; i++)
{
mq = &c->rx_queues[i];
@@ -1068,7 +1142,7 @@ memif_disconnect_internal (memif_connection_t * c)
mq->int_fd = -1;
}
}
- free (c->rx_queues);
+ lm->free (c->rx_queues);
c->rx_queues = NULL;
}
@@ -1079,13 +1153,13 @@ memif_disconnect_internal (memif_connection_t * c)
if (c->regions[0].fd > 0)
close (c->regions[0].fd);
c->regions[0].fd = -1;
- free (c->regions);
+ lm->free (c->regions);
c->regions = NULL;
}
memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
- memif_msg_queue_free (&c->msg_queue);
+ memif_msg_queue_free (lm, &c->msg_queue);
if (!(c->args.is_master))
{
@@ -1094,7 +1168,7 @@ memif_disconnect_internal (memif_connection_t * c)
if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
{
err = memif_syscall_error_handler (errno);
- DBG_UNIX ("timerfd_settime: arm");
+ DBG ("timerfd_settime: arm");
}
}
lm->disconn_slaves++;
@@ -1145,11 +1219,11 @@ memif_delete (memif_conn_handle_t * conn)
c->listener_fd);
close (c->listener_fd);
c->listener_fd = ms->fd = -1;
- free (ms->interface_list);
+ lm->free (ms->interface_list);
ms->interface_list = NULL;
- free (ms->filename);
+ lm->free (ms->filename);
ms->filename = NULL;
- free (ms);
+ lm->free (ms);
ms = NULL;
}
}
@@ -1168,10 +1242,10 @@ memif_delete (memif_conn_handle_t * conn)
}
if (c->args.socket_filename)
- free (c->args.socket_filename);
+ lm->free (c->args.socket_filename);
c->args.socket_filename = NULL;
- free (c);
+ lm->free (c);
c = NULL;
*conn = c;
@@ -1203,8 +1277,8 @@ memif_connect1 (memif_connection_t * c)
}
num =
- (c->args.is_master) ? c->run_args.num_m2s_rings : c->
- run_args.num_s2m_rings;
+ (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+ num_s2m_rings;
for (i = 0; i < num; i++)
{
mq = &c->tx_queues[i];
@@ -1221,8 +1295,8 @@ memif_connect1 (memif_connection_t * c)
}
}
num =
- (c->args.is_master) ? c->run_args.num_s2m_rings : c->
- run_args.num_m2s_rings;
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+ num_m2s_rings;
for (i = 0; i < num; i++)
{
mq = &c->rx_queues[i];
@@ -1254,9 +1328,9 @@ memif_init_regions_and_queues (memif_connection_t * conn)
libmemif_main_t *lm = &libmemif_main;
memif_list_elt_t e;
- conn->regions = (memif_region_t *) malloc (sizeof (memif_region_t));
+ conn->regions = (memif_region_t *) lm->alloc (sizeof (memif_region_t));
if (conn->regions == NULL)
- return memif_syscall_error_handler (errno);
+ return MEMIF_ERR_NOMEM;
r = conn->regions;
buffer_offset =
@@ -1269,12 +1343,13 @@ memif_init_regions_and_queues (memif_connection_t * conn)
conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
(conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
- if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
+ if ((r->fd =
+ memif_memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
return memif_syscall_error_handler (errno);
-/*
- if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
- return memif_syscall_error_handler (errno);
-*/
+
+ if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
+ return memif_syscall_error_handler (errno);
+
if ((ftruncate (r->fd, r->region_size)) == -1)
return memif_syscall_error_handler (errno);
@@ -1295,7 +1370,7 @@ memif_init_regions_and_queues (memif_connection_t * conn)
ring->desc[j].region = 0;
ring->desc[j].offset = buffer_offset +
(uint32_t) (slot * conn->run_args.buffer_size);
- ring->desc[j].buffer_length = conn->run_args.buffer_size;
+ ring->desc[j].length = conn->run_args.buffer_size;
}
}
for (i = 0; i < conn->run_args.num_m2s_rings; i++)
@@ -1314,15 +1389,15 @@ memif_init_regions_and_queues (memif_connection_t * conn)
ring->desc[j].region = 0;
ring->desc[j].offset = buffer_offset +
(uint32_t) (slot * conn->run_args.buffer_size);
- ring->desc[j].buffer_length = conn->run_args.buffer_size;
+ ring->desc[j].length = conn->run_args.buffer_size;
}
}
memif_queue_t *mq;
mq =
- (memif_queue_t *) malloc (sizeof (memif_queue_t) *
- conn->run_args.num_s2m_rings);
+ (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
+ conn->run_args.num_s2m_rings);
if (mq == NULL)
- return memif_syscall_error_handler (errno);
+ return MEMIF_ERR_NOMEM;
int x;
for (x = 0; x < conn->run_args.num_s2m_rings; x++)
{
@@ -1340,15 +1415,16 @@ memif_init_regions_and_queues (memif_connection_t * conn)
mq[x].offset =
(void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
mq[x].last_head = 0;
+ mq[x].last_tail = 0;
mq[x].alloc_bufs = 0;
}
conn->tx_queues = mq;
mq =
- (memif_queue_t *) malloc (sizeof (memif_queue_t) *
- conn->run_args.num_m2s_rings);
+ (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
+ conn->run_args.num_m2s_rings);
if (mq == NULL)
- return memif_syscall_error_handler (errno);
+ return MEMIF_ERR_NOMEM;
for (x = 0; x < conn->run_args.num_m2s_rings; x++)
{
if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
@@ -1365,6 +1441,7 @@ memif_init_regions_and_queues (memif_connection_t * conn)
mq[x].offset =
(void *) mq[x].ring - (void *) conn->regions[mq->region].shm;
mq[x].last_head = 0;
+ mq[x].last_tail = 0;
mq[x].alloc_bufs = 0;
}
conn->rx_queues = mq;
@@ -1378,101 +1455,102 @@ memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
uint16_t * count_out, uint16_t size)
{
memif_connection_t *c = (memif_connection_t *) conn;
- if (c == NULL)
+ if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (c->fd < 0)
+ if (EXPECT_FALSE (c->fd < 0))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
- (c->args.is_master) ? c->run_args.num_m2s_rings : c->
- run_args.num_s2m_rings;
- if (qid >= num)
+ (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+ num_s2m_rings;
+ if (EXPECT_FALSE (qid >= num))
return MEMIF_ERR_QID;
+ if (EXPECT_FALSE (!count_out))
+ return MEMIF_ERR_INVAL_ARG;
+
memif_queue_t *mq = &c->tx_queues[qid];
memif_ring_t *ring = mq->ring;
memif_buffer_t *b0, *b1;
- uint8_t chain_buf = 1;
uint16_t mask = (1 << mq->log2_ring_size) - 1;
- uint16_t head = ring->head;
- uint16_t tail = ring->tail;
uint16_t ring_size;
- uint16_t s0, s1, ns;
- *count_out = 0;
+ uint16_t slot, ns;
int i, err = MEMIF_ERR_SUCCESS; /* 0 */
+ uint16_t dst_left, src_left;
+ uint16_t saved_count;
+ memif_buffer_t *saved_b;
+ *count_out = 0;
ring_size = (1 << mq->log2_ring_size);
- ns = ring_size - head + tail;
+ ns = ring->tail - mq->last_tail;
+ mq->last_tail += ns;
+ slot = (c->args.is_master) ? ring->tail : ring->head;
+ slot += mq->alloc_bufs;
- /* calculate number of chain buffers */
- if (size > ring->desc[0].buffer_length)
- {
- chain_buf = size / ring->desc[0].buffer_length;
- if (((size % ring->desc[0].buffer_length) != 0) || (size == 0))
- chain_buf++;
- }
+ if (c->args.is_master)
+ ns = ring->head + mq->alloc_bufs - ring->tail;
+ else
+ ns = ring_size - ring->head + mq->alloc_bufs + mq->last_tail;
while (count && ns)
{
- while ((count > 2) && (ns > 2))
- {
- s0 = (ring->head + mq->alloc_bufs) & mask;
- s1 = (ring->head + mq->alloc_bufs + chain_buf) & mask;
-
- if ((2 * chain_buf) > ns)
- break;
-
- b0 = (bufs + *count_out);
- b1 = (bufs + *count_out + 1);
-
- b0->desc_index = head + mq->alloc_bufs;
- b1->desc_index = head + mq->alloc_bufs + chain_buf;
- ring->desc[s0].flags = 0;
- ring->desc[s1].flags = 0;
- b0->buffer_len = ring->desc[s0].buffer_length * chain_buf;
- b1->buffer_len = ring->desc[s1].buffer_length * chain_buf;
- /* TODO: support multiple regions -> ring descriptor contains region index */
- b0->data = c->regions->shm + ring->desc[s0].offset;
- b1->data = c->regions->shm + ring->desc[s1].offset;
-
- for (i = 0; i < (chain_buf - 1); i++)
- {
- ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
- ring->desc[(s1 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
- DBG ("allocating chained buffers");
- }
-
- mq->alloc_bufs += 2 * chain_buf;
-
- DBG ("allocated ring slots %u, %u", s0, s1);
- count -= 2;
- ns -= (2 * chain_buf);
- *count_out += 2;
- }
- s0 = (ring->head + mq->alloc_bufs) & mask;
-
b0 = (bufs + *count_out);
- if (chain_buf > ns)
- break;
+ saved_b = b0;
+ saved_count = count;
+
+ b0->desc_index = slot;
+ ring->desc[slot & mask].flags = 0;
- b0->desc_index = head + mq->alloc_bufs;
- ring->desc[s0].flags = 0;
- b0->buffer_len = ring->desc[s0].buffer_length * chain_buf;
- b0->data = c->regions->shm + ring->desc[s0].offset;
+ /* slave can produce buffer with original length */
+ dst_left = (c->args.is_master) ? ring->desc[slot & mask].length : c->run_args.buffer_size; /* - headroom */
+ src_left = size;
- for (i = 0; i < (chain_buf - 1); i++)
+ while (src_left)
{
- ring->desc[(s0 + i) & mask].flags |= MEMIF_DESC_FLAG_NEXT;
- DBG ("allocating chained buffers");
- }
+ if (dst_left == 0)
+ {
+ if (count && ns)
+ {
+ slot++;
+ *count_out += 1;
+ mq->alloc_bufs++;
+ ns--;
+ count--;
+
+ ring->desc[b0->desc_index & mask].flags |=
+ MEMIF_DESC_FLAG_NEXT;
+ b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
+
+ b0 = (bufs + *count_out);
+ b0->desc_index = slot;
+ dst_left = (c->args.is_master) ? ring->desc[slot & mask].length : c->run_args.buffer_size; /* - headroom */
+ ring->desc[slot & mask].flags = 0;
+ }
+ else
+ {
+ /* rollback allocated chain buffers */
+ memset (saved_b, 0, sizeof (memif_buffer_t)
+ * (saved_count - count + 1));
+ *count_out -= saved_count - count;
+ mq->alloc_bufs = saved_count - count;
+ goto no_ns;
+ }
+ }
+ b0->len = memif_min (dst_left, src_left);
+ b0->data = memif_get_buffer (c, ring, slot & mask);
- mq->alloc_bufs += chain_buf;
+ src_left -= b0->len;
+ dst_left -= b0->len;
+ }
- DBG ("allocated ring slot %u", s0);
- count--;
- ns -= chain_buf;
+ slot++;
*count_out += 1;
+ mq->alloc_bufs++;
+ ns--;
+ count--;
}
+no_ns:
+
DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
mq->alloc_bufs);
@@ -1486,72 +1564,37 @@ memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
}
int
-memif_buffer_free (memif_conn_handle_t conn, uint16_t qid,
- memif_buffer_t * bufs, uint16_t count,
- uint16_t * count_out)
+memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count)
{
memif_connection_t *c = (memif_connection_t *) conn;
- if (c == NULL)
+ if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (c->fd < 0)
+ if (EXPECT_FALSE (c->fd < 0))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
- (c->args.is_master) ? c->run_args.num_s2m_rings : c->
- run_args.num_m2s_rings;
- if (qid >= num)
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+ num_m2s_rings;
+ if (EXPECT_FALSE (qid >= num))
return MEMIF_ERR_QID;
libmemif_main_t *lm = &libmemif_main;
memif_queue_t *mq = &c->rx_queues[qid];
memif_ring_t *ring = mq->ring;
- uint16_t tail = ring->tail;
- uint16_t mask = (1 << mq->log2_ring_size) - 1;
- uint8_t chain_buf0, chain_buf1;
- memif_buffer_t *b0, *b1;
- *count_out = 0;
- if (mq->alloc_bufs < count)
- count = mq->alloc_bufs;
-
- while (count)
+ if (c->args.is_master)
{
- while (count > 2)
- {
- b0 = (bufs + *count_out);
- b1 = (bufs + *count_out + 1);
- chain_buf0 =
- b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
- if ((b0->buffer_len %
- ring->desc[b0->desc_index & mask].buffer_length) != 0)
- chain_buf0++;
- chain_buf1 =
- b1->buffer_len / ring->desc[b1->desc_index & mask].buffer_length;
- if ((b1->buffer_len %
- ring->desc[b1->desc_index & mask].buffer_length) != 0)
- chain_buf1++;
- tail = b1->desc_index + chain_buf1;
- b0->data = NULL;
- b1->data = NULL;
-
- count -= 2;
- *count_out += 2;
- mq->alloc_bufs -= chain_buf0 + chain_buf1;
- }
- b0 = (bufs + *count_out);
- chain_buf0 =
- b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
- if ((b0->buffer_len %
- ring->desc[b0->desc_index & mask].buffer_length) != 0)
- chain_buf0++;
- tail = b0->desc_index + chain_buf0;
- b0->data = NULL;
-
- count--;
- *count_out += 1;
- mq->alloc_bufs -= chain_buf0;
+ MEMIF_MEMORY_BARRIER ();
+ ring->tail =
+ (ring->tail + count <=
+ mq->last_head) ? ring->tail + count : mq->last_head;
+ }
+ else
+ {
+ uint16_t head = ring->head;
+ uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
+ head += ns;
+ MEMIF_MEMORY_BARRIER ();
+ ring->head = (ring->head + count <= head) ? ring->head + count : head;
}
- MEMIF_MEMORY_BARRIER ();
- ring->tail = tail;
- DBG ("tail: %u", ring->tail);
return MEMIF_ERR_SUCCESS; /* 0 */
}
@@ -1561,212 +1604,48 @@ memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
{
memif_connection_t *c = (memif_connection_t *) conn;
- if (c == NULL)
+ if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (c->fd < 0)
+ if (EXPECT_FALSE (c->fd < 0))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
- (c->args.is_master) ? c->run_args.num_m2s_rings : c->
- run_args.num_s2m_rings;
- if (qid >= num)
+ (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+ num_s2m_rings;
+ if (EXPECT_FALSE (qid >= num))
return MEMIF_ERR_QID;
+ if (EXPECT_FALSE (!tx))
+ return MEMIF_ERR_INVAL_ARG;
+
memif_queue_t *mq = &c->tx_queues[qid];
memif_ring_t *ring = mq->ring;
- uint16_t head = ring->head;
- uint16_t mask = (1 << mq->log2_ring_size) - 1;
- uint8_t chain_buf0, chain_buf1;
- *tx = 0;
- uint16_t curr_buf = 0;
- memif_buffer_t *b0, *b1;
- int i;
+ uint16_t slot;
- while (count)
- {
- while (count > 2)
- {
- b0 = (bufs + curr_buf);
- b1 = (bufs + curr_buf + 1);
- chain_buf0 =
- b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
- if ((b0->buffer_len %
- ring->desc[b0->desc_index & mask].buffer_length) != 0)
- chain_buf0++;
-
- chain_buf1 =
- b1->buffer_len / ring->desc[b1->desc_index & mask].buffer_length;
- if ((b1->buffer_len %
- ring->desc[b1->desc_index & mask].buffer_length) != 0)
- chain_buf1++;
-
- for (i = 0; i < memif_min (chain_buf0, chain_buf1); i++)
- {
- /* b0 */
- if (b0->data_len >
- ring->desc[(b0->desc_index + i) & mask].buffer_length)
- {
- b0->data_len -=
- ring->desc[(b0->desc_index + i) & mask].length =
- ring->desc[(b0->desc_index + i) & mask].buffer_length;
- }
- else
- {
- ring->desc[(b0->desc_index + i) & mask].length =
- b0->data_len;
- b0->data_len = 0;
- }
- /* b1 */
- if (b1->data_len >
- ring->desc[(b1->desc_index + i) & mask].buffer_length)
- {
- b1->data_len -=
- ring->desc[(b1->desc_index + i) & mask].length =
- ring->desc[(b1->desc_index + i) & mask].buffer_length;
- }
- else
- {
- ring->desc[(b1->desc_index + i) & mask].length =
- b1->data_len;
- b1->data_len = 0;
- }
-#ifdef MEMIF_DBG_SHM
- print_bytes (b0->data +
- ring->desc[(b0->desc_index +
- i) & mask].buffer_length *
- (chain_buf0 - 1),
- ring->desc[(b0->desc_index +
- i) & mask].buffer_length, DBG_TX_BUF);
- print_bytes (b1->data +
- ring->desc[(b1->desc_index +
- i) & mask].buffer_length *
- (chain_buf1 - 1),
- ring->desc[(b1->desc_index +
- i) & mask].buffer_length, DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- }
+ slot = (c->args.is_master) ? ring->tail : ring->head;
+ *tx = (count <= mq->alloc_bufs) ? count : mq->alloc_bufs;
- if (chain_buf0 > chain_buf1)
- {
- for (; i < chain_buf0; i++)
- {
- if (b0->data_len >
- ring->desc[(b0->desc_index + i) & mask].buffer_length)
- {
- b0->data_len -=
- ring->desc[(b0->desc_index + i) & mask].length =
- ring->desc[(b0->desc_index + i) & mask].buffer_length;
- }
- else
- {
- ring->desc[(b0->desc_index + i) & mask].length =
- b0->data_len;
- b0->data_len = 0;
- }
-#ifdef MEMIF_DBG_SHM
- print_bytes (b0->data +
- ring->desc[(b0->desc_index +
- i) & mask].buffer_length *
- (chain_buf0 - 1),
- ring->desc[(b0->desc_index +
- i) & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- }
- }
- else
- {
- for (; i < chain_buf1; i++)
- {
- if (b1->data_len >
- ring->desc[(b1->desc_index + i) & mask].buffer_length)
- {
- b1->data_len -=
- ring->desc[(b1->desc_index + i) & mask].length =
- ring->desc[(b1->desc_index + i) & mask].buffer_length;
- }
- else
- {
- ring->desc[(b1->desc_index + i) & mask].length =
- b1->data_len;
- b1->data_len = 0;
- }
#ifdef MEMIF_DBG_SHM
- print_bytes (b1->data +
- ring->desc[(b1->desc_index +
- i) & mask].buffer_length *
- (chain_buf1 - 1),
- ring->desc[(b1->desc_index +
- i) & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- }
- }
-
- head = b1->desc_index + chain_buf1;
-
- b0->data = NULL;
-#ifdef MEMIF_DBG
- if (b0->data_len != 0)
- DBG ("invalid b0 data length!");
-#endif /* MEMIF_DBG */
- b1->data = NULL;
-#ifdef MEMIF_DBG
- if (b1->data_len != 0)
- DBG ("invalid b1 data length!");
-#endif /* MEMIF_DBG */
-
- count -= 2;
- *tx += chain_buf0 + chain_buf1;
- curr_buf += 2;
- }
-
+ uint16_t curr_buf = 0;
+ uint16_t mask = (1 << mq->log2_ring_size) - 1;
+ memif_buffer_t *b0;
+ for (curr_buf = 0; curr_buf < count; curr_buf++)
+ {
b0 = (bufs + curr_buf);
- chain_buf0 =
- b0->buffer_len / ring->desc[b0->desc_index & mask].buffer_length;
- if ((b0->buffer_len %
- ring->desc[b0->desc_index & mask].buffer_length) != 0)
- chain_buf0++;
+ print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
+ ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
- for (i = 0; i < chain_buf0; i++)
- {
- if (b0->data_len >
- ring->desc[(b0->desc_index + i) & mask].buffer_length)
- {
- b0->data_len -= ring->desc[(b0->desc_index + i) & mask].length =
- ring->desc[(b0->desc_index + i) & mask].buffer_length;
- }
- else
- {
- ring->desc[(b0->desc_index + i) & mask].length = b0->data_len;
- b0->data_len = 0;
- }
-#ifdef MEMIF_DBG_SHM
- print_bytes (b0->data +
- ring->desc[(b0->desc_index + i) & mask].buffer_length *
- (chain_buf0 - 1),
- ring->desc[(b0->desc_index + i) & mask].buffer_length,
- DBG_TX_BUF);
+ }
#endif /* MEMIF_DBG_SHM */
- }
-
- head = b0->desc_index + chain_buf0;
- b0->data = NULL;
-#ifdef MEMIF_DBG
- if (b0->data_len != 0)
- DBG ("invalid b0 data length!");
-#endif /* MEMIF_DBG */
-
- count--;
- *tx += chain_buf0;
- curr_buf++;
- }
MEMIF_MEMORY_BARRIER ();
- ring->head = head;
+ if (c->args.is_master)
+ ring->tail = slot + *tx;
+ else
+ ring->head = slot + *tx;
- mq->alloc_bufs -= *tx;
+ /* zero out buffer fields so the client cant modify transmitted data */
+ memset (bufs, 0, sizeof (memif_buffer_t) * *tx);
- /* TODO: return num of buffers and packets */
- *tx = curr_buf;
+ mq->alloc_bufs -= *tx;
if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
{
@@ -1784,154 +1663,70 @@ memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
{
memif_connection_t *c = (memif_connection_t *) conn;
- if (c == NULL)
+ if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (c->fd < 0)
+ if (EXPECT_FALSE (c->fd < 0))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
- (c->args.is_master) ? c->run_args.num_s2m_rings : c->
- run_args.num_m2s_rings;
- if (qid >= num)
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+ num_m2s_rings;
+ if (EXPECT_FALSE (qid >= num))
return MEMIF_ERR_QID;
+ if (EXPECT_FALSE (!rx))
+ return MEMIF_ERR_INVAL_ARG;
+
memif_queue_t *mq = &c->rx_queues[qid];
memif_ring_t *ring = mq->ring;
- uint16_t head = ring->head;
+ uint16_t cur_slot, last_slot;
uint16_t ns;
uint16_t mask = (1 << mq->log2_ring_size) - 1;
memif_buffer_t *b0, *b1;
- uint16_t curr_buf = 0;
*rx = 0;
-#ifdef MEMIF_DBG_SHM
- int i;
-#endif /* MEMIF_DBG_SHM */
uint64_t b;
ssize_t r = read (mq->int_fd, &b, sizeof (b));
if ((r == -1) && (errno != EAGAIN))
return memif_syscall_error_handler (errno);
- if (head == mq->last_head)
- return 0;
+ cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
+ last_slot = (c->args.is_master) ? ring->head : ring->tail;
+ if (cur_slot == last_slot)
+ return MEMIF_ERR_SUCCESS;
- ns = head - mq->last_head;
+ ns = last_slot - cur_slot;
while (ns && count)
{
- while ((ns > 2) && (count > 2))
- {
- b0 = (bufs + curr_buf);
- b1 = (bufs + curr_buf + 1);
-
- b0->desc_index = mq->last_head;
- b0->data = memif_get_buffer (conn, ring, mq->last_head & mask);
- b0->data_len = ring->desc[mq->last_head & mask].length;
- b0->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
- i = 0;
- print_bytes (b0->data +
- ring->desc[b0->desc_index & mask].buffer_length * i++,
- ring->desc[b0->desc_index & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- ns--;
- *rx += 1;
- while (ring->desc[mq->last_head & mask].
- flags & MEMIF_DESC_FLAG_NEXT)
- {
- ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
- mq->last_head++;
- b0->data_len += ring->desc[mq->last_head & mask].length;
- b0->buffer_len +=
- ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
- print_bytes (b0->data +
- ring->desc[b0->desc_index & mask].buffer_length *
- i++,
- ring->desc[b0->desc_index & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- ns--;
- *rx += 1;
- }
- mq->last_head++;
-
- b1->desc_index = mq->last_head;
- b1->data = memif_get_buffer (conn, ring, mq->last_head & mask);
- b1->data_len = ring->desc[mq->last_head & mask].length;
- b1->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
- i = 0;
- print_bytes (b1->data +
- ring->desc[b1->desc_index & mask].buffer_length * i++,
- ring->desc[b1->desc_index & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- ns--;
- *rx += 1;
- while (ring->desc[mq->last_head & mask].
- flags & MEMIF_DESC_FLAG_NEXT)
- {
- ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
- mq->last_head++;
- b1->data_len += ring->desc[mq->last_head & mask].length;
- b1->buffer_len +=
- ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
- print_bytes (b1->data +
- ring->desc[b1->desc_index & mask].buffer_length *
- i++,
- ring->desc[b1->desc_index & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- ns--;
- *rx += 1;
- }
- mq->last_head++;
+ b0 = (bufs + *rx);
- count -= 2;
- curr_buf += 2;
+ b0->desc_index = cur_slot;
+ b0->data = memif_get_buffer (c, ring, cur_slot & mask);
+ b0->len = ring->desc[cur_slot & mask].length;
+ /* slave resets buffer length */
+ if (c->args.is_master == 0)
+ {
+ ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
+ }
+ if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
+ {
+ b0->flags = MEMIF_BUFFER_FLAG_NEXT;
+ ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
}
- b0 = (bufs + curr_buf);
- b0->desc_index = mq->last_head;
- b0->data = memif_get_buffer (conn, ring, mq->last_head & mask);
- b0->data_len = ring->desc[mq->last_head & mask].length;
- b0->buffer_len = ring->desc[mq->last_head & mask].buffer_length;
#ifdef MEMIF_DBG_SHM
- i = 0;
- print_bytes (b0->data +
- ring->desc[b0->desc_index & mask].buffer_length * i++,
- ring->desc[b0->desc_index & mask].buffer_length,
- DBG_TX_BUF);
+ print_bytes (b0->data, b0->len, DBG_RX_BUF);
#endif /* MEMIF_DBG_SHM */
ns--;
*rx += 1;
- while (ring->desc[mq->last_head & mask].flags & MEMIF_DESC_FLAG_NEXT)
- {
- ring->desc[mq->last_head & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
- mq->last_head++;
- b0->data_len += ring->desc[mq->last_head & mask].length;
- b0->buffer_len += ring->desc[mq->last_head & mask].buffer_length;
-#ifdef MEMIF_DBG_SHM
- print_bytes (b0->data +
- ring->desc[b0->desc_index & mask].buffer_length * i++,
- ring->desc[b0->desc_index & mask].buffer_length,
- DBG_TX_BUF);
-#endif /* MEMIF_DBG_SHM */
- ns--;
- *rx += 1;
- }
- mq->last_head++;
-
count--;
- curr_buf++;
+ cur_slot++;
}
- mq->alloc_bufs += *rx;
-
- /* TODO: return num of buffers and packets */
- *rx = curr_buf;
+ if (c->args.is_master)
+ mq->last_head = cur_slot;
+ else
+ mq->last_tail = cur_slot;
if (ns)
{
@@ -1946,6 +1741,7 @@ int
memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
char *buf, ssize_t buflen)
{
+ libmemif_main_t *lm = &libmemif_main;
memif_connection_t *c = (memif_connection_t *) conn;
if (c == NULL)
return MEMIF_ERR_NOCONN;
@@ -1963,10 +1759,10 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
else
err = MEMIF_ERR_NOBUF_DET;
- l1 = strlen ((char *) c->args.instance_name);
+ l1 = strlen ((char *) lm->app_name);
if (l0 + l1 < buflen)
{
- md->inst_name = strcpy (buf + l0, (char *) c->args.instance_name);
+ md->inst_name = strcpy (buf + l0, (char *) lm->app_name);
l0 += l1 + 1;
}
else
@@ -2018,8 +1814,8 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
err = MEMIF_ERR_NOBUF_DET;
md->rx_queues_num =
- (c->args.is_master) ? c->run_args.num_s2m_rings : c->
- run_args.num_m2s_rings;
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+ num_m2s_rings;
l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
if (l0 + l1 <= buflen)
@@ -2041,8 +1837,8 @@ memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
}
md->tx_queues_num =
- (c->args.is_master) ? c->run_args.num_m2s_rings : c->
- run_args.num_s2m_rings;
+ (c->args.is_master) ? c->run_args.num_m2s_rings : c->run_args.
+ num_s2m_rings;
l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
if (l0 + l1 <= buflen)
@@ -2078,8 +1874,8 @@ memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
if (c->fd < 0)
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
- (c->args.is_master) ? c->run_args.num_s2m_rings : c->
- run_args.num_m2s_rings;
+ (c->args.is_master) ? c->run_args.num_s2m_rings : c->run_args.
+ num_m2s_rings;
if (qid >= num)
return MEMIF_ERR_QID;
@@ -2093,16 +1889,16 @@ memif_cleanup ()
{
libmemif_main_t *lm = &libmemif_main;
if (lm->control_list)
- free (lm->control_list);
+ lm->free (lm->control_list);
lm->control_list = NULL;
if (lm->interrupt_list)
- free (lm->interrupt_list);
+ lm->free (lm->interrupt_list);
lm->interrupt_list = NULL;
if (lm->listener_list)
- free (lm->listener_list);
+ lm->free (lm->listener_list);
lm->listener_list = NULL;
if (lm->pending_list)
- free (lm->pending_list);
+ lm->free (lm->pending_list);
lm->pending_list = NULL;
if (poll_cancel_fd != -1)
close (poll_cancel_fd);
diff --git a/extras/libmemif/src/memif.h b/extras/libmemif/src/memif.h
index 11918eabcde..38b54029e46 100644
--- a/extras/libmemif/src/memif.h
+++ b/extras/libmemif/src/memif.h
@@ -22,8 +22,8 @@
#define MEMIF_CACHELINE_SIZE 64
#endif
-#define MEMIF_COOKIE 0x3E31F10
-#define MEMIF_VERSION_MAJOR 1
+#define MEMIF_COOKIE 0x3E31F20
+#define MEMIF_VERSION_MAJOR 2
#define MEMIF_VERSION_MINOR 0
#define MEMIF_VERSION ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
@@ -58,7 +58,7 @@ typedef enum
} memif_interface_mode_t;
typedef uint16_t memif_region_index_t;
-typedef uint64_t memif_region_offset_t;
+typedef uint32_t memif_region_offset_t;
typedef uint64_t memif_region_size_t;
typedef uint16_t memif_ring_index_t;
typedef uint32_t memif_interface_id_t;
@@ -148,15 +148,13 @@ typedef struct __attribute__ ((packed))
uint16_t flags;
#define MEMIF_DESC_FLAG_NEXT (1 << 0)
memif_region_index_t region;
- uint32_t buffer_length;
uint32_t length;
- uint8_t reserved[4];
memif_region_offset_t offset;
- uint64_t metadata;
+ uint32_t metadata;
} memif_desc_t;
-_Static_assert (sizeof (memif_desc_t) == 32,
- "Size of memif_dsct_t must be 32");
+_Static_assert (sizeof (memif_desc_t) == 16,
+ "Size of memif_dsct_t must be 16 bytes");
#define MEMIF_CACHELINE_ALIGN_MARK(mark) \
uint8_t mark[0] __attribute__((aligned(MEMIF_CACHELINE_SIZE)))
diff --git a/extras/libmemif/src/memif_private.h b/extras/libmemif/src/memif_private.h
index a512ed4eaaa..b1039f9d385 100644
--- a/extras/libmemif/src/memif_private.h
+++ b/extras/libmemif/src/memif_private.h
@@ -28,6 +28,7 @@
#include <sys/timerfd.h>
#include <string.h>
+#include <memif.h>
#include <libmemif.h>
#define MEMIF_NAME_LEN 32
@@ -45,43 +46,23 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
#define MEMIF_MAX_M2S_RING 255
#define MEMIF_MAX_S2M_RING 255
#define MEMIF_MAX_REGION 255
-#define MEMIF_MAX_LOG2_RING_SIZE 15
+#define MEMIF_MAX_LOG2_RING_SIZE 14
#define MEMIF_MAX_FDS 512
#define memif_min(a,b) (((a) < (b)) ? (a) : (b))
+#define EXPECT_TRUE(x) __builtin_expect((x),1)
+#define EXPECT_FALSE(x) __builtin_expect((x),0)
+
#ifdef MEMIF_DBG
#define DBG(...) do { \
printf("MEMIF_DEBUG:%s:%s:%d: ", __FILE__, __func__, __LINE__); \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
-
-#define DBG_UNIX(...) do { \
- printf("MEMIF_DEBUG_UNIX:%s:%s:%d: ", __FILE__, __func__, __LINE__); \
- printf(__VA_ARGS__); \
- printf("\n"); \
- } while (0)
-
-#define error_return_unix(...) do { \
- DBG_UNIX(__VA_ARGS__); \
- return -1; \
- } while (0)
-#define error_return(...) do { \
- DBG(__VA_ARGS__); \
- return -1; \
- } while (0)
#else
#define DBG(...)
-#define DBG_UNIX(...)
-#define error_return_unix(...) do { \
- return -1; \
- } while (0)
-#define error_return(...) do { \
- return -1; \
- } while (0)
-
#endif /* MEMIF_DBG */
typedef struct
@@ -160,18 +141,12 @@ typedef struct memif_connection
#define MEMIF_CONNECTION_FLAG_WRITE (1 << 0)
} memif_connection_t;
-/*
- * WIP
- */
typedef struct
{
- int key; /* fd or id */
+ int key;
void *data_struct;
} memif_list_elt_t;
-/*
- * WIP
- */
typedef struct
{
int fd;
@@ -181,10 +156,6 @@ typedef struct
memif_list_elt_t *interface_list; /* memif master interfaces listening on this socket */
} memif_socket_t;
-/*
- * WIP
- */
-/* probably function like memif_cleanup () will need to be called to close timerfd */
typedef struct
{
memif_control_fd_update_t *control_fd_update;
@@ -193,8 +164,8 @@ typedef struct
uint16_t disconn_slaves;
uint8_t app_name[MEMIF_NAME_LEN];
- /* master implementation... */
- memif_socket_t ms;
+ memif_alloc_t *alloc;
+ memif_free_t *free;
uint16_t control_list_len;
uint16_t interrupt_list_len;
@@ -244,7 +215,7 @@ int free_list_elt (memif_list_elt_t * list, uint16_t len, int key);
#ifndef HAVE_MEMFD_CREATE
static inline int
-memfd_create (const char *name, unsigned int flags)
+memif_memfd_create (const char *name, unsigned int flags)
{
return syscall (__NR_memfd_create, name, flags);
}
diff --git a/extras/libmemif/src/socket.c b/extras/libmemif/src/socket.c
index 2be40f8669d..8f18d892139 100644
--- a/extras/libmemif/src/socket.c
+++ b/extras/libmemif/src/socket.c
@@ -32,6 +32,7 @@
#include <socket.h>
#include <memif.h>
+#include <memif_private.h>
/* sends msg to socket */
static_fn int
@@ -70,8 +71,9 @@ memif_msg_send (int fd, memif_msg_t * msg, int afd)
static_fn int
memif_msg_enq_ack (memif_connection_t * c)
{
+ libmemif_main_t *lm = &libmemif_main;
memif_msg_queue_elt_t *e =
- (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+ (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
if (e == NULL)
return memif_syscall_error_handler (errno);
@@ -121,8 +123,9 @@ memif_msg_send_hello (int fd)
static_fn int
memif_msg_enq_init (memif_connection_t * c)
{
+ libmemif_main_t *lm = &libmemif_main;
memif_msg_queue_elt_t *e =
- (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+ (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
if (e == NULL)
return memif_syscall_error_handler (errno);
memset (e, 0, sizeof (memif_msg_queue_elt_t));
@@ -136,8 +139,8 @@ memif_msg_enq_init (memif_connection_t * c)
i->id = c->args.interface_id;
i->mode = c->args.mode;
- strncpy ((char *) i->name, (char *) c->args.instance_name,
- strlen ((char *) c->args.instance_name));
+ strncpy ((char *) i->name, (char *) lm->app_name,
+ strlen ((char *) lm->app_name));
if (c->args.secret)
strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
@@ -162,11 +165,12 @@ memif_msg_enq_init (memif_connection_t * c)
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 =
- (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+ (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
if (e == NULL)
return memif_syscall_error_handler (errno);
@@ -199,8 +203,9 @@ memif_msg_enq_add_region (memif_connection_t * c, uint8_t region_index)
static_fn int
memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
{
+ libmemif_main_t *lm = &libmemif_main;
memif_msg_queue_elt_t *e =
- (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+ (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
if (e == NULL)
return memif_syscall_error_handler (errno);
@@ -244,8 +249,9 @@ memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
static_fn int
memif_msg_enq_connect (memif_connection_t * c)
{
+ libmemif_main_t *lm = &libmemif_main;
memif_msg_queue_elt_t *e =
- (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+ (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
if (e == NULL)
return memif_syscall_error_handler (errno);
@@ -278,8 +284,9 @@ memif_msg_enq_connect (memif_connection_t * c)
static_fn int
memif_msg_enq_connected (memif_connection_t * c)
{
+ libmemif_main_t *lm = &libmemif_main;
memif_msg_queue_elt_t *e =
- (memif_msg_queue_elt_t *) malloc (sizeof (memif_msg_queue_elt_t));
+ (memif_msg_queue_elt_t *) lm->alloc (sizeof (memif_msg_queue_elt_t));
if (e == NULL)
return memif_syscall_error_handler (errno);
@@ -519,7 +526,7 @@ memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
mq =
(memif_queue_t *) realloc (c->rx_queues,
sizeof (memif_queue_t) * (ar->index + 1));
- memset(mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
+ memset (mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
if (mq == NULL)
return memif_syscall_error_handler (errno);
c->rx_queues = mq;
@@ -539,7 +546,7 @@ memif_msg_receive_add_ring (memif_connection_t * c, memif_msg_t * msg, int fd)
mq =
(memif_queue_t *) realloc (c->tx_queues,
sizeof (memif_queue_t) * (ar->index + 1));
- memset(mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
+ memset (mq, 0, sizeof (memif_queue_t) * (ar->index + 1));
if (mq == NULL)
return memif_syscall_error_handler (errno);
c->tx_queues = mq;
@@ -579,6 +586,9 @@ memif_msg_receive_connect (memif_connection_t * c, memif_msg_t * msg)
add_list_elt (&elt, &lm->interrupt_list, &lm->interrupt_list_len);
lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+
+ /* refill ring buffers */
+ memif_refill_queue ((void *) c, i, -1);
}
}
@@ -607,7 +617,12 @@ memif_msg_receive_connected (memif_connection_t * c, memif_msg_t * msg)
if (c->on_interrupt != NULL)
{
for (i = 0; i < c->run_args.num_s2m_rings; i++)
- lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+ {
+ lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ);
+
+ /* refill ring buffers */
+ memif_refill_queue ((void *) c, i, -1);
+ }
}
c->on_connect ((void *) c, c->private_ctx);
@@ -814,6 +829,7 @@ memif_conn_fd_read_ready (memif_connection_t * c)
int
memif_conn_fd_write_ready (memif_connection_t * c)
{
+ libmemif_main_t *lm = &libmemif_main;
int err = MEMIF_ERR_SUCCESS; /* 0 */
@@ -834,7 +850,7 @@ memif_conn_fd_write_ready (memif_connection_t * c)
MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_WRITE | MEMIF_FD_EVENT_MOD);
*/
err = memif_msg_send (c->fd, &e->msg, e->fd);
- free (e);
+ lm->free (e);
goto done;
done: