43 #define DEBUG_MESSAGE_BUFFER_OVERRUN 0 58 #if DEBUG_MESSAGE_BUFFER_OVERRUN > 0 88 for (i = 0; i <
vec_len (ap); i++)
91 if (nbytes > ap[i].
size)
99 pthread_mutex_lock (&q->mutex);
101 rv = (
msgbuf_t *) (&q->data[0] + q->head * q->elsize);
117 u16 *msg_idp, msg_id;
119 (
"garbage collect pool %d ring %d index %d", pool, i,
122 msg_id = clib_net_to_host_u16 (*msg_idp);
136 pthread_mutex_unlock (&q->mutex);
150 if (q->head == q->maxsize)
154 pthread_mutex_unlock (&q->mutex);
164 pthread_mutex_lock (&am->vlib_rp->mutex);
172 pthread_mutex_unlock (&am->vlib_rp->mutex);
180 rv->gc_mark_timestamp = 0;
182 pthread_mutex_unlock (&am->vlib_rp->mutex);
185 #if DEBUG_MESSAGE_BUFFER_OVERRUN > 0 189 overrun = (
u32 *) (rv->data + nbytes - sizeof (
msgbuf_t));
190 *overrun = 0x1badbabe;
193 rv->data_len = htonl (nbytes -
sizeof (
msgbuf_t));
292 #if DEBUG_MESSAGE_BUFFER_OVERRUN > 0 296 ASSERT (*overrun == 0x1badbabe);
305 #if DEBUG_MESSAGE_BUFFER_OVERRUN > 0 309 ASSERT (*overrun == 0x1badbabe);
410 u32 vlib_input_queue_length;
413 vlib_input_queue_length = 1024;
424 _rp.rp = svm_queue_alloc_and_init ((n), (sz), 0); \ 429 vec_add1(shmem_hdr->vl_rings, _rp); \ 438 _rp.rp = svm_queue_alloc_and_init ((n), (sz), 0); \ 443 vec_add1(shmem_hdr->client_rings, _rp); \ 493 int is_vlib,
int is_private_region)
511 if (is_private_region == 0)
530 pthread_mutex_unlock (&vlib_rp->
mutex);
540 struct timespec ts, tsrem;
541 char *vpe_api_region_suffix =
"-vpe-api";
545 if (strstr (region_name, vpe_api_region_suffix))
547 u8 *root_path =
format (0,
"%s", region_name);
548 _vec_len (root_path) = (
vec_len (root_path) -
549 strlen (vpe_api_region_suffix));
552 am->
root_path = (
const char *) root_path;
566 api_name =
format (0,
"/dev/shm%s%c", region_name, 0);
569 for (i = 0; i < 10000; i++)
572 ts.tv_nsec = 10000 * 1000;
573 while (nanosleep (&ts, &tsrem) < 0)
575 tfd = open ((
char *) api_name, O_RDWR);
591 a->
name =
"/vpe-api";
594 a->
name = region_name;
606 pthread_mutex_lock (&vlib_rp->
mutex);
629 for (i = 0; i < 10; i++)
631 if (pthread_mutex_trylock (&q->mutex) == 0)
633 pthread_mutex_unlock (&q->mutex);
637 ts.tv_nsec = 10000 * 1000;
638 while (nanosleep (&ts, &tsrem) < 0)
643 clib_warning (
"forcibly release main input queue mutex");
653 pthread_mutex_unlock (&vlib_rp->
mutex);
657 pthread_mutex_lock (&root_rp->
mutex);
659 pthread_mutex_unlock (&root_rp->
mutex);
663 pthread_mutex_unlock (&vlib_rp->
mutex);
672 pthread_mutex_unlock (&vlib_rp->
mutex);
675 for (i = 0; i < 10000; i++)
678 ts.tv_nsec = 10000 * 1000;
679 while (nanosleep (&ts, &tsrem) < 0)
767 (am->
vl_clients && (q->cursize == q->maxsize)))
774 .format =
"api-client-queue-stuffed: %x%x",
775 .format_args =
"i4i4",
783 ed->hi = (
uword) q >> 32;
784 ed->low = (
uword) q & 0xFFFFFFFF;
785 clib_warning (
"WARNING: client input queue at %llx is stuffed...",
795 return (q->cursize < q->maxsize);
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u64 api_pvt_heap_size
size of the api private mheap
void svm_region_init_chroot_uid_gid(const char *root_path, int uid, int gid)
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
svm_region_t * svm_get_root_rp(void)
static void svm_pop_heap(void *oldheap)
int svm_queue_add(svm_queue_t *q, u8 *elem, int nowait)
void vl_set_global_memory_baseva(u64 baseva)
int vl_map_shmem(const char *region_name, int is_vlib)
u64 api_size
size of the API region
Optimized string handling code, including c11-compliant "safe C library" variants.
void vl_set_memory_uid(int uid)
void vl_set_global_pvt_heap_size(u64 size)
void vl_unmap_shmem(void)
u32 gc_mark_timestamp
message garbage collector mark TS
#define vec_terminate_c_string(V)
(If necessary) NULL terminate a vector containing a c-string.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static void vl_unmap_shmem_internal(u8 is_client)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
int api_uid
uid for the api shared memory region
void svm_region_unmap_client(void *rp_arg)
ring_alloc_t * client_rings
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
svm_queue_t * q
message allocated in this shmem ring
int vl_mem_api_can_send(svm_queue_t *q)
void svm_region_exit_client(void)
u8 data[0]
actual message begins here
struct msgbuf_ msgbuf_t
Message header structure.
void * vl_msg_api_alloc_zero_as_if_client(int nbytes)
void * vl_msg_api_alloc_zero(int nbytes)
void * vl_msg_api_alloc(int nbytes)
int api_gid
gid for the api shared memory region
void vl_set_global_memory_size(u64 size)
int our_pid
Current process PID.
void svm_region_exit(void)
int svm_queue_sub(svm_queue_t *q, u8 *elem, svm_q_conditional_wait_t cond, u32 time)
#define foreach_clnt_aring_size
static void * svm_push_data_heap(svm_region_t *rp)
vl_api_registration_t ** vl_clients
vlib/vpp only: vector of client registrations
void * svm_region_find_or_create(svm_map_region_args_t *a)
const char * root_path
Chroot path to the shared memory API files.
svm_region_t * vlib_rp
Current binary api segment descriptor.
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
struct ring_alloc_ ring_alloc_t
void vl_set_memory_root_path(const char *name)
void vl_register_mapped_shmem_region(svm_region_t *rp)
void vl_init_shmem(svm_region_t *vlib_rp, vl_api_shm_elem_config_t *config, int is_vlib, int is_private_region)
#define VL_API_INVALID_FI
int elog_trace_api_messages
void(** msg_print_handlers)(void *, void *)
Message print function vector.
void vl_set_api_pvt_heap_size(u64 size)
elog_main_t * elog_main
event log
API main structure, used by both vpp and binary API clients.
u64 global_size
size of the global VM region
u8 enabled
trace is enabled
An API client registration, only in vpp/vlib.
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
static_always_inline uword vlib_get_thread_index(void)
static void * clib_mem_alloc_or_null(uword size)
u64 global_baseva
base virtual address for global VM region
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
void vl_msg_api_trace(api_main_t *am, vl_api_trace_t *tp, void *msg)
void vl_set_memory_gid(int gid)
static void vl_msg_api_free_nolock(void *a)
void vl_msg_api_free(void *a)
#define ELOG_TYPE_DECLARE(f)
const char ** msg_names
Message name vector.
svm_queue_t * vl_input_queue
void vl_unmap_shmem_client(void)
vl_api_trace_t * tx_trace
Sent message trace configuration.
u32 data_len
message length not including header
Message header structure.
svm_queue_t * svm_queue_alloc_and_init(int nels, int elsize, int consumer_pid)
Allocate and initialize svm queue.
static void clib_mem_free(void *p)
u64 global_pvt_heap_size
size of the global VM private mheap
static void vl_api_default_mem_config(vl_shmem_hdr_t *shmem_hdr)
static void * clib_mem_alloc(uword size)
#define foreach_vl_aring_size
void vl_api_mem_config(vl_shmem_hdr_t *hdr, vl_api_shm_elem_config_t *config)
void(** msg_endian_handlers)(void *)
Message endian handler vector.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void svm_region_unmap(void *rp_arg)
void svm_client_scan_this_region_nolock(svm_region_t *rp)
int svm_queue_add_nolock(svm_queue_t *q, u8 *elem)
static void * vl_msg_api_alloc_internal(int nbytes, int pool, int may_return_null)
struct _svm_queue svm_queue_t
void * vl_msg_api_alloc_as_if_client_or_null(int nbytes)
void * vl_mem_api_alloc_as_if_client_w_reg(vl_api_registration_t *reg, int nbytes)
void(** msg_handlers)(void *)
Message handler vector.
void vl_set_api_memory_size(u64 size)
#define vec_foreach(var, vec)
Vector iterator.
void * vl_msg_api_alloc_as_if_client(int nbytes)
void * vl_msg_api_alloc_or_null(int nbytes)
svm_region_t ** mapped_shmem_regions
void vl_msg_api_send_shmem_nolock(svm_queue_t *q, u8 *elem)
u32 vlib_input_queue_length
vpp/vlib input queue length
non-blocking call - works with both condvar and eventfd signaling
static svm_region_t * root_rp