31 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) 44 vl_print (handle,
"vl_api_memclnt_create_t:\n");
55 vl_print (handle,
"vl_api_memclnt_delete_t:\n");
88 shmem_hdr = (
void *) vlib_rp->
user_ctx;
125 pthread_mutex_lock (&svm->
mutex);
130 memset (regp, 0,
sizeof (*regp));
139 pthread_mutex_unlock (&svm->
mutex);
192 pthread_mutex_lock (&svm->
mutex);
197 memset (regp, 0,
sizeof (*regp));
218 pthread_mutex_unlock (&svm->
mutex);
222 rp->_vl_msg_id = ntohs (VL_API_MEMCLNT_CREATE_REPLY);
238 _vl_msg_api_function_list_elt_t *
i;
243 error = i->f (client_index);
246 i = i->next_init_function;
263 u32 handle, client_index, epoch;
276 (
"Stale clnt delete index %d old epoch %d cur epoch %d",
289 int private_registration = 0;
296 rp->_vl_msg_id = ntohs (VL_API_MEMCLNT_DELETE_REPLY);
329 if (munmap ((
void *) virtual_base, virtual_size) < 0)
333 private_registration = 1;
341 if (private_registration == 0)
345 pthread_mutex_lock (&svm->
mutex);
349 memset (regp, 0xF1,
sizeof (*regp));
351 pthread_mutex_unlock (&svm->
mutex);
373 (vl_api_memclnt_keepalive_reply_t * mp)
385 clib_warning (
"BUG: anonymous memclnt_keepalive_reply");
395 vl_api_memclnt_keepalive_reply_t *rmp;
403 memset (rmp, 0,
sizeof (*rmp));
404 rmp->_vl_msg_id = ntohs (VL_API_MEMCLNT_KEEPALIVE_REPLY);
409 #define foreach_vlib_api_msg \ 410 _(MEMCLNT_CREATE, memclnt_create) \ 411 _(MEMCLNT_DELETE, memclnt_delete) \ 412 _(MEMCLNT_KEEPALIVE, memclnt_keepalive) \ 413 _(MEMCLNT_KEEPALIVE_REPLY, memclnt_keepalive_reply) \ 428 memset (c, 0,
sizeof (*c));
433 #define _(N,n) do { \ 434 c->id = VL_API_##N; \ 436 c->handler = vl_api_##n##_t_handler; \ 437 c->cleanup = vl_noop_handler; \ 438 c->endian = vl_api_##n##_t_endian; \ 439 c->print = vl_api_##n##_t_print; \ 440 c->size = sizeof(vl_api_##n##_t); \ 443 c->message_bounce = 0; \ 444 vl_msg_api_config(c);} while (0); 454 am->
is_mp_safe[VL_API_MEMCLNT_KEEPALIVE_REPLY] = 1;
516 memset (mp, 0,
sizeof (*mp));
517 mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_MEMCLNT_KEEPALIVE);
537 u32 ** confused_indices)
549 if (kill (q->consumer_pid, 0) >= 0)
581 static u32 *dead_indices;
582 static u32 *confused_indices;
589 vl_mem_send_client_keepalive_w_reg (am, now, regpp, &dead_indices,
598 for (i = 0; i <
vec_len (confused_indices); i++)
611 for (i = 0; i <
vec_len (dead_indices); i++)
625 pthread_mutex_lock (&svm->
mutex);
628 for (i = 0; i <
vec_len (dead_indices); i++)
634 if ((*regpp)->vlib_rp != svm)
653 if (munmap ((
void *) virtual_base, virtual_size) < 0)
661 memset (*regpp, 0xF3,
sizeof (**regpp));
678 pthread_mutex_unlock (&svm->
mutex);
680 for (i = 0; i <
vec_len (dead_indices); i++)
765 if (index == (
u32) ~ 0)
788 int main_segment = va_arg (*args,
int);
793 return format (s,
"%8s %8s %8s %8s %8s\n",
794 "Owner",
"Size",
"Nitems",
"Hits",
"Misses");
800 s =
format (s,
"%8s %8d %8d %8d %8d\n",
809 s =
format (s,
"%8s %8d %8d %8d %8d\n",
819 "%d application restarts, %d reclaimed msgs, %d garbage collects\n",
855 shmem_hdr = (
void *) vlib_rp->
user_ctx;
864 if (regp && regp->vlib_rp == vlib_rp)
889 .path =
"show api ring-stats",
890 .short_help =
"Message ring statistics",
901 u8 *remove_path1, *remove_path2;
909 remove_path1 =
format (0,
"/dev/shm/global_vm%c", 0);
910 remove_path2 =
format (0,
"/dev/shm/vpe-api%c", 0);
914 remove_path1 =
format (0,
"/dev/shm/%s-global_vm%c", am->
root_path, 0);
918 (void) unlink ((
char *) remove_path1);
919 (void) unlink ((
char *) remove_path2);
924 memset (a, 0,
sizeof (*a));
int vl_mem_api_handle_msg_private(vlib_main_t *vm, vlib_node_runtime_t *node, u32 reg_index)
int vl_mem_api_handle_msg_main(vlib_main_t *vm, vlib_node_runtime_t *node)
static u32 vl_msg_api_handle_get_index(u32 index)
void vl_api_memclnt_create_t_handler(vl_api_memclnt_create_t *mp)
#define SVM_GLOBAL_REGION_NAME
static void * vl_api_memclnt_create_t_print(vl_api_memclnt_create_t *a, void *handle)
static void vl_api_memclnt_keepalive_t_handler(vl_api_memclnt_keepalive_t *mp)
We can send ourselves these messages if someone uses the builtin binary api test tool...
static void svm_pop_heap(void *oldheap)
#define vl_print(handle,...)
int svm_queue_add(svm_queue_t *q, u8 *elem, int nowait)
u32 vl_api_memclnt_create_internal(char *name, svm_queue_t *q)
static void send_memclnt_keepalive(vl_api_registration_t *regp, f64 now)
int vl_map_shmem(const char *region_name, int is_vlib)
volatile int ** vl_api_queue_cursizes
static f64 vlib_time_now(vlib_main_t *vm)
void vl_unmap_shmem(void)
int svm_queue_sub2(svm_queue_t *q, u8 *elem)
u8 * message_bounce
Don't automatically free message buffer vetor.
Message configuration definition.
svm_region_t * vlib_primary_rp
Primary api segment descriptor.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define SVM_PVT_MHEAP_SIZE
int api_uid
uid for the api shared memory region
ring_alloc_t * client_rings
#define pool_is_free(P, E)
Use free bitmap to query whether given element is free.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
void * vl_msg_api_alloc(int nbytes)
int api_gid
gid for the api shared memory region
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
_vl_msg_api_function_list_elt_t * reaper_function_registrations
List of API client reaper functions.
u8 * format_api_message_rings(u8 *s, va_list *args)
u32 clib_file_index
Socket only: file index.
memset(h->entries, 0, sizeof(h->entries[0])*entries)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
u32 ring_misses
Number of times that the ring allocator failed.
static void * svm_push_data_heap(svm_region_t *rp)
vl_api_registration_t ** vl_clients
vlib/vpp only: vector of client registrations
vl_api_registration_t * vl_mem_api_client_index_to_registration(u32 handle)
static clib_error_t * vl_api_ring_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cli_cmd)
static u32 vl_msg_api_handle_from_index_and_epoch(u32 index, u32 epoch)
void vl_api_memclnt_keepalive_reply_t_handler(vl_api_memclnt_keepalive_reply_t *mp)
client answered a ping, stave off the grim reaper...
void vl_mem_api_dead_client_scan(api_main_t *am, vl_shmem_hdr_t *shm, f64 now)
vlib_node_registration_t vl_api_clnt_node
(constructor) VLIB_REGISTER_NODE (vl_api_clnt_node)
const char * root_path
Chroot path to the shared memory API files.
#define clib_error_return(e, args...)
svm_region_t * vlib_rp
Current binary api segment descriptor.
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
#define vlib_call_init_function(vm, x)
static void vlib_set_queue_signal_callback(vlib_main_t *vm, void(*fp)(vlib_main_t *))
vl_shmem_hdr_t * shmem_hdr
vl_registration_type_t registration_type
type
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define foreach_vlib_api_msg
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
svm_queue_t * vl_input_queue
shared memory only: pointer to client input queue
svm_region_t ** vlib_private_rps
Vector of all mapped shared-VM segments.
void svm_region_init_args(svm_map_region_args_t *a)
#define SVM_GLOBAL_REGION_SIZE
void vl_msg_api_handler_with_vm_node(api_main_t *am, void *the_msg, vlib_main_t *vm, vlib_node_runtime_t *node)
clib_error_t * vlibmemory_init(vlib_main_t *vm)
volatile u32 queue_signal_pending
clib_error_t * map_api_segment_init(vlib_main_t *vm)
API main structure, used by both vpp and binary API clients.
u64 global_size
size of the global VM region
An API client registration, only in vpp/vlib.
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
Shared memory connection.
static_always_inline uword vlib_get_thread_index(void)
svm_queue_t * vl_api_client_index_to_input_queue(u32 index)
u64 global_baseva
base virtual address for global VM region
static clib_error_t * setup_memclnt_exit(vlib_main_t *vm)
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
static void * vl_api_memclnt_delete_t_print(vl_api_memclnt_delete_t *a, void *handle)
u8 * vl_api_serialize_message_table(api_main_t *am, u8 *vector)
static int void_mem_api_handle_msg_i(api_main_t *am, vlib_main_t *vm, vlib_node_runtime_t *node, svm_queue_t *q)
clib_error_t * vlibsocket_init(vlib_main_t *vm)
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
svm_queue_t * vl_input_queue
#define VLIB_CLI_COMMAND(x,...)
static u32 vl_msg_api_handle_get_epoch(u32 index)
#define pool_put_index(p, i)
Free pool element with given index.
int vl_mem_api_init(const char *region_name)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
static u8 vl_msg_api_handle_is_valid(u32 handle, u32 restarts)
static void vl_mem_send_client_keepalive_w_reg(api_main_t *am, f64 now, vl_api_registration_t **regpp, u32 **dead_indices, u32 **confused_indices)
static void clib_mem_free(void *p)
void vl_set_memory_region_name(const char *name)
u64 svm_get_global_region_base_va()
u8 * serialized_message_table_in_shmem
vlib/vpp only: serialized (message, name, crc) table
#define clib_error_report(e)
u64 global_pvt_heap_size
size of the global VM private mheap
void vl_api_memclnt_delete_t_handler(vl_api_memclnt_delete_t *mp)
static void * clib_mem_alloc(uword size)
static uword pointer_to_uword(const void *p)
static vlib_main_t * vlib_get_main(void)
void vl_msg_api_free(void *)
#define VL_API_EPOCH_MASK
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void memclnt_queue_callback(vlib_main_t *vm)
#define clib_unix_warning(format, args...)
u32 vl_api_registration_pool_index
Index in VLIB's brain (not shared memory).
void svm_client_scan_this_region_nolock(svm_region_t *rp)
volatile u32 api_queue_nonempty
struct _svm_queue svm_queue_t
u8 * is_mp_safe
Message is mp safe vector.
void vl_msg_api_increment_missing_client_counter(void)
int vl_api_call_reaper_functions(u32 client_index)
void * vl_msg_api_alloc_as_if_client(int nbytes)
const char * region_name
Shared VM binary API region name.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)