#include <vppinfra/format.h>
#include <vppinfra/byte_order.h>
#include <vppinfra/error.h>
+#include <vppinfra/elog.h>
#include <svm/queue.h>
#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <vlibmemory/memory_api.h>
#include <vlibmemory/vl_memory_msg_enum.h>
+#include <vlibapi/api_common.h>
#define vl_typedefs
#include <vlibmemory/vl_memory_api_h.h>
#define DEBUG_MESSAGE_BUFFER_OVERRUN 0
-static inline void *
-vl_msg_api_alloc_internal (int nbytes, int pool, int may_return_null)
+CLIB_NOSANITIZE_ADDR static inline void *
+vl_msg_api_alloc_internal (svm_region_t * vlib_rp, int nbytes, int pool,
+ int may_return_null)
{
int i;
msgbuf_t *rv;
svm_queue_t *q;
void *oldheap;
vl_shmem_hdr_t *shmem_hdr;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
- shmem_hdr = am->shmem_hdr;
+ shmem_hdr = (void *) vlib_rp->user_ctx;
#if DEBUG_MESSAGE_BUFFER_OVERRUN > 0
nbytes += 4;
q->head);
msg_idp = (u16 *) (rv->data);
msg_id = clib_net_to_host_u16 (*msg_idp);
- if (msg_id < vec_len (api_main.msg_names))
+ if (msg_id < vec_len (vlibapi_get_main ()->msg_names))
clib_warning ("msg id %d name %s", (u32) msg_id,
- api_main.msg_names[msg_id]);
+ vlibapi_get_main ()->msg_names[msg_id]);
}
shmem_hdr->garbage_collects++;
goto collected;
*/
am->ring_misses++;
- pthread_mutex_lock (&am->vlib_rp->mutex);
- oldheap = svm_push_data_heap (am->vlib_rp);
+ oldheap = vl_msg_push_heap_w_region (vlib_rp);
if (may_return_null)
{
rv = clib_mem_alloc_or_null (nbytes);
if (PREDICT_FALSE (rv == 0))
{
- svm_pop_heap (oldheap);
- pthread_mutex_unlock (&am->vlib_rp->mutex);
+ vl_msg_pop_heap_w_region (vlib_rp, oldheap);
return 0;
}
}
rv->q = 0;
rv->gc_mark_timestamp = 0;
- svm_pop_heap (oldheap);
- pthread_mutex_unlock (&am->vlib_rp->mutex);
+ vl_msg_pop_heap_w_region (vlib_rp, oldheap);
out:
#if DEBUG_MESSAGE_BUFFER_OVERRUN > 0
#endif
rv->data_len = htonl (nbytes - sizeof (msgbuf_t));
+ VL_MSG_API_UNPOISON (rv->data);
return (rv->data);
}
vl_msg_api_alloc (int nbytes)
{
int pool;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
/*
* Clients use pool-0, vlib proc uses pool 1
*/
pool = (am->our_pid == shmem_hdr->vl_pid);
- return vl_msg_api_alloc_internal (nbytes, pool, 0 /* may_return_null */ );
+ return vl_msg_api_alloc_internal (am->vlib_rp, nbytes, pool,
+ 0 /* may_return_null */ );
+}
+
+void *
+vl_msg_api_alloc_zero (int nbytes)
+{
+ void *ret;
+
+ ret = vl_msg_api_alloc (nbytes);
+ clib_memset (ret, 0, nbytes);
+ return ret;
}
void *
vl_msg_api_alloc_or_null (int nbytes)
{
int pool;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
pool = (am->our_pid == shmem_hdr->vl_pid);
- return vl_msg_api_alloc_internal (nbytes, pool, 1 /* may_return_null */ );
+ return vl_msg_api_alloc_internal (am->vlib_rp, nbytes, pool,
+ 1 /* may_return_null */ );
}
void *
vl_msg_api_alloc_as_if_client (int nbytes)
{
- return vl_msg_api_alloc_internal (nbytes, 0, 0 /* may_return_null */ );
+ api_main_t *am = vlibapi_get_main ();
+ return vl_msg_api_alloc_internal (am->vlib_rp, nbytes, 0,
+ 0 /* may_return_null */ );
+}
+
+void *
+vl_msg_api_alloc_zero_as_if_client (int nbytes)
+{
+ void *ret;
+
+ ret = vl_msg_api_alloc_as_if_client (nbytes);
+ clib_memset (ret, 0, nbytes);
+ return ret;
}
void *
vl_msg_api_alloc_as_if_client_or_null (int nbytes)
{
- return vl_msg_api_alloc_internal (nbytes, 0, 1 /* may_return_null */ );
+ api_main_t *am = vlibapi_get_main ();
+ return vl_msg_api_alloc_internal (am->vlib_rp, nbytes, 0,
+ 1 /* may_return_null */ );
}
void *
vl_mem_api_alloc_as_if_client_w_reg (vl_api_registration_t * reg, int nbytes)
{
- api_main_t *am = &api_main;
- vl_shmem_hdr_t *save_shmem_hdr = am->shmem_hdr;
- svm_region_t *vlib_rp, *save_vlib_rp = am->vlib_rp;
- void *msg;
-
- vlib_rp = am->vlib_rp = reg->vlib_rp;
- am->shmem_hdr = (void *) vlib_rp->user_ctx;
-
- msg = vl_msg_api_alloc_internal (nbytes, 0, 0 /* may_return_null */ );
-
- am->shmem_hdr = save_shmem_hdr;
- am->vlib_rp = save_vlib_rp;
-
- return msg;
+ return vl_msg_api_alloc_internal (reg->vlib_rp, nbytes, 0,
+ 0 /* may_return_null */ );
}
void
-vl_msg_api_free (void *a)
+vl_msg_api_free_w_region (svm_region_t * vlib_rp, void *a)
{
msgbuf_t *rv;
void *oldheap;
- api_main_t *am = &api_main;
rv = (msgbuf_t *) (((u8 *) a) - offsetof (msgbuf_t, data));
ASSERT (*overrun == 0x1badbabe);
}
#endif
+ VL_MSG_API_POISON (rv->data);
return;
}
- pthread_mutex_lock (&am->vlib_rp->mutex);
- oldheap = svm_push_data_heap (am->vlib_rp);
+ oldheap = vl_msg_push_heap_w_region (vlib_rp);
#if DEBUG_MESSAGE_BUFFER_OVERRUN > 0
{
#endif
clib_mem_free (rv);
- svm_pop_heap (oldheap);
- pthread_mutex_unlock (&am->vlib_rp->mutex);
+ vl_msg_pop_heap_w_region (vlib_rp, oldheap);
+}
+
+void
+vl_msg_api_free (void *a)
+{
+ api_main_t *am = vlibapi_get_main ();
+ vl_msg_api_free_w_region (am->vlib_rp, a);
}
static void
{
msgbuf_t *rv;
void *oldheap;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
rv = (msgbuf_t *) (((u8 *) a) - offsetof (msgbuf_t, data));
/*
if (rv->q)
{
rv->q = 0;
+ VL_MSG_API_POISON (rv->data);
return;
}
void
vl_set_memory_root_path (const char *name)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->root_path = name;
}
void
vl_set_memory_uid (int uid)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->api_uid = uid;
}
void
vl_set_memory_gid (int gid)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->api_gid = gid;
}
void
vl_set_global_memory_baseva (u64 baseva)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->global_baseva = baseva;
}
void
vl_set_global_memory_size (u64 size)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->global_size = size;
}
void
vl_set_api_memory_size (u64 size)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->api_size = size;
}
void
vl_set_global_pvt_heap_size (u64 size)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->global_pvt_heap_size = size;
}
void
vl_set_api_pvt_heap_size (u64 size)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
am->api_pvt_heap_size = size;
}
static void
vl_api_default_mem_config (vl_shmem_hdr_t * shmem_hdr)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
u32 vlib_input_queue_length;
/* vlib main input queue */
vl_init_shmem (svm_region_t * vlib_rp, vl_api_shm_elem_config_t * config,
int is_vlib, int is_private_region)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
vl_shmem_hdr_t *shmem_hdr = 0;
void *oldheap;
ASSERT (vlib_rp);
{
svm_map_region_args_t _a, *a = &_a;
svm_region_t *vlib_rp, *root_rp;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
int i;
struct timespec ts, tsrem;
char *vpe_api_region_suffix = "-vpe-api";
while (nanosleep (&ts, &tsrem) < 0)
ts = tsrem;
tfd = open ((char *) api_name, O_RDWR);
- if (tfd > 0)
+ if (tfd >= 0)
break;
}
vec_free (api_name);
void
vl_register_mapped_shmem_region (svm_region_t * rp)
{
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
vec_add1 (am->mapped_shmem_regions, rp);
}
{
svm_region_t *rp;
int i;
- api_main_t *am = &api_main;
+ api_main_t *am = vlibapi_get_main ();
if (!svm_get_root_rp ())
return;
void
vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem)
{
- api_main_t *am = &api_main;
- uword *trace = (uword *) elem;
+ api_main_t *am = vlibapi_get_main ();
+ void *msg = (void *) *(uword *) elem;
if (am->tx_trace && am->tx_trace->enabled)
- vl_msg_api_trace (am, am->tx_trace, (void *) trace[0]);
+ vl_msg_api_trace (am, am->tx_trace, msg);
/*
* Announce a probable binary API client bug:
*/
if (PREDICT_FALSE
(am->vl_clients /* vpp side */ && (q->cursize == q->maxsize)))
- clib_warning ("WARNING: client input queue at %llx is stuffed...", q);
+ {
+ if (PREDICT_FALSE (am->elog_trace_api_messages))
+ {
+ /* *INDENT-OFF* */
+ ELOG_TYPE_DECLARE (e) =
+ {
+ .format = "api-client-queue-stuffed: %x%x",
+ .format_args = "i4i4",
+ };
+ /* *INDENT-ON* */
+ struct
+ {
+ u32 hi, low;
+ } *ed;
+ ed = ELOG_DATA (am->elog_main, e);
+ ed->hi = (uword) q >> 32;
+ ed->low = (uword) q & 0xFFFFFFFF;
+ clib_warning ("WARNING: client input queue at %llx is stuffed...",
+ q);
+ }
+ }
+ VL_MSG_API_POISON (msg);
(void) svm_queue_add (q, elem, 0 /* nowait */ );
}
void
vl_msg_api_send_shmem_nolock (svm_queue_t * q, u8 * elem)
{
- api_main_t *am = &api_main;
- uword *trace = (uword *) elem;
+ api_main_t *am = vlibapi_get_main ();
+ void *msg = (void *) *(uword *) elem;
if (am->tx_trace && am->tx_trace->enabled)
- vl_msg_api_trace (am, am->tx_trace, (void *) trace[0]);
+ vl_msg_api_trace (am, am->tx_trace, msg);
(void) svm_queue_add_nolock (q, elem);
+ VL_MSG_API_POISON (msg);
}
/*