vl_api_trace_plugin_msg_ids_t_print (vl_api_trace_plugin_msg_ids_t * a,
void *handle)
{
- vl_print (handle, "vl_api_trace_plugin_msg_ids: %s first %u last %u\n",
- a->plugin_name,
+ u8 *plugin_name = vl_api_from_api_to_vec (&a->plugin_name);
+ vl_print (handle, "vl_api_trace_plugin_msg_ids: %v first %u last %u\n",
+ plugin_name,
clib_host_to_net_u16 (a->first_msg_id),
clib_host_to_net_u16 (a->last_msg_id));
+ vec_free (plugin_name);
return handle;
}
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun
-u8 *
-vl_api_serialize_message_table (api_main_t * am, u8 * vector)
-{
- serialize_main_t _sm, *sm = &_sm;
- hash_pair_t *hp;
- u32 nmsg = hash_elts (am->msg_index_by_name_and_crc);
-
- serialize_open_vector (sm, vector);
-
- /* serialize the count */
- serialize_integer (sm, nmsg, sizeof (u32));
-
- /* *INDENT-OFF* */
- hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
- ({
- serialize_likely_small_unsigned_integer (sm, hp->value[0]);
- serialize_cstring (sm, (char *) hp->key);
- }));
- /* *INDENT-ON* */
-
- return serialize_close_vector (sm);
-}
-
static void
vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t * mp)
{
uword *p;
api_main_t *am = &api_main;
vl_api_msg_range_t *rp;
- u8 name[64];
u16 first_msg_id = ~0;
int rv = -7; /* VNET_API_ERROR_INVALID_VALUE */
if (!regp)
return;
+ u8 *name = vl_api_from_api_to_vec (&mp->name);
+
if (am->msg_range_by_name == 0)
goto out;
- strncpy ((char *) name, (char *) mp->name, ARRAY_LEN (name));
- name[ARRAY_LEN (name) - 1] = '\0';
+
p = hash_get_mem (am->msg_range_by_name, name);
if (p == 0)
goto out;
rv = 0;
out:
+ vec_free (name);
rmp = vl_msg_api_alloc (sizeof (*rmp));
rmp->_vl_msg_id = ntohs (VL_API_GET_FIRST_MSG_ID_REPLY);
rmp->context = mp->context;
return;
rmp = vl_msg_api_alloc (msg_size);
- memset (rmp, 0, msg_size);
+ clib_memset (rmp, 0, msg_size);
rmp->_vl_msg_id = ntohs (VL_API_API_VERSIONS_REPLY);
/* fill in the message */
rmp->api_versions[i].major = htonl (vl->major);
rmp->api_versions[i].minor = htonl (vl->minor);
rmp->api_versions[i].patch = htonl (vl->patch);
- strncpy ((char *) rmp->api_versions[i].name, vl->name,
- ARRAY_LEN (rmp->api_versions[i].name));
- rmp->api_versions[i].name[ARRAY_LEN (rmp->api_versions[i].name) - 1] =
- '\0';
+ vl_api_to_api_string (strnlen (vl->name, 64), vl->name,
+ &rmp->api_versions[i].name);
}
vl_api_send_msg (reg, (u8 *) rmp);
vl_msg_api_msg_config_t cfg;
vl_msg_api_msg_config_t *c = &cfg;
- memset (c, 0, sizeof (*c));
+ clib_memset (c, 0, sizeof (*c));
#define _(N,n) do { \
c->id = VL_API_##N; \
svm_queue_t *q;
mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
- memset (mp, 0, sizeof (*mp));
+ clib_memset (mp, 0, sizeof (*mp));
mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_TRACE_PLUGIN_MSG_IDS);
- strncpy ((char *) mp->plugin_name, (char *) name,
- sizeof (mp->plugin_name) - 1);
+ vl_api_to_api_string (strnlen_s ((char *) name, 64), (char *) name,
+ &mp->plugin_name);
mp->first_msg_id = clib_host_to_net_u16 (first_msg_id);
mp->last_msg_id = clib_host_to_net_u16 (last_msg_id);
q = shm->vl_input_queue;
e = vlib_call_init_exit_functions
- (vm, vm->api_init_function_registrations, 1 /* call_once */ );
+ (vm, &vm->api_init_function_registrations, 1 /* call_once */ );
if (e)
clib_error_report (e);
start_time = vlib_time_now (vm);
while (1)
{
- if (vl_mem_api_handle_msg_main (vm, node))
+ if (vl_mem_api_handle_rpc (vm, node)
+ || vl_mem_api_handle_msg_main (vm, node))
{
vm->api_queue_nonempty = 0;
VL_MEM_API_LOG_Q_LEN ("q-underflow: len %d", 0);
vec_validate (long_msg, 4095);
n_left_from = frame->n_vectors;
- from = vlib_frame_args (frame);
+ from = vlib_frame_vector_args (frame);
while (n_left_from > 0)
{
}
/* Free what we've been given. */
- vlib_buffer_free (vm, vlib_frame_args (frame), n_packets);
+ vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_packets);
return n_packets;
}
void
vl_api_send_pending_rpc_requests (vlib_main_t * vm)
{
- api_main_t *am = &api_main;
- vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
- svm_queue_t *q;
- int i;
-
- /*
- * Use the "normal" control-plane mechanism for the main thread.
- * Well, almost. if the main input queue is full, we cannot
- * block. Otherwise, we can expect a barrier sync timeout.
- */
- q = shmem_hdr->vl_input_queue;
-
- for (i = 0; i < vec_len (vm->pending_rpc_requests); i++)
- {
- while (pthread_mutex_trylock (&q->mutex))
- vlib_worker_thread_barrier_check ();
-
- while (PREDICT_FALSE (svm_queue_is_full (q)))
- {
- pthread_mutex_unlock (&q->mutex);
- vlib_worker_thread_barrier_check ();
- while (pthread_mutex_trylock (&q->mutex))
- vlib_worker_thread_barrier_check ();
- }
+ vlib_main_t *vm_global = &vlib_global_main;
- vl_msg_api_send_shmem_nolock (q, (u8 *) (vm->pending_rpc_requests + i));
+ ASSERT (vm != vm_global);
- pthread_mutex_unlock (&q->mutex);
- }
- _vec_len (vm->pending_rpc_requests) = 0;
+ clib_spinlock_lock_if_init (&vm_global->pending_rpc_lock);
+ vec_append (vm_global->pending_rpc_requests, vm->pending_rpc_requests);
+ vec_reset_length (vm->pending_rpc_requests);
+ clib_spinlock_unlock_if_init (&vm_global->pending_rpc_lock);
}
always_inline void
u8 force_rpc)
{
vl_api_rpc_call_t *mp;
+ vlib_main_t *vm_global = &vlib_global_main;
vlib_main_t *vm = vlib_get_main ();
/* Main thread and not a forced RPC: call the function directly */
/* Otherwise, actually do an RPC */
mp = vl_msg_api_alloc_as_if_client (sizeof (*mp) + data_length);
- memset (mp, 0, sizeof (*mp));
- clib_memcpy (mp->data, data, data_length);
+ clib_memset (mp, 0, sizeof (*mp));
+ clib_memcpy_fast (mp->data, data, data_length);
mp->_vl_msg_id = ntohs (VL_API_RPC_CALL);
mp->function = pointer_to_uword (fp);
mp->need_barrier_sync = 1;
+ /* Add to the pending vector. Thread 0 requires locking. */
+ if (vm == vm_global)
+ clib_spinlock_lock_if_init (&vm_global->pending_rpc_lock);
vec_add1 (vm->pending_rpc_requests, (uword) mp);
+ if (vm == vm_global)
+ clib_spinlock_unlock_if_init (&vm_global->pending_rpc_lock);
}
/*
if (am->replay_in_progress == 0)
return;
- p = hash_get_mem (am->msg_range_by_name, mp->plugin_name);
+ u8 *plugin_name = vl_api_from_api_to_vec (&mp->plugin_name);
+ vec_add1 (plugin_name, 0);
+
+ p = hash_get_mem (am->msg_range_by_name, plugin_name);
if (p == 0)
{
clib_warning ("WARNING: traced plugin '%s' not in current image",
- mp->plugin_name);
+ plugin_name);
return;
}
if (rp->first_msg_id != clib_net_to_host_u16 (mp->first_msg_id))
{
clib_warning ("WARNING: traced plugin '%s' first message id %d not %d",
- mp->plugin_name, clib_net_to_host_u16 (mp->first_msg_id),
+ plugin_name, clib_net_to_host_u16 (mp->first_msg_id),
rp->first_msg_id);
}
if (rp->last_msg_id != clib_net_to_host_u16 (mp->last_msg_id))
{
clib_warning ("WARNING: traced plugin '%s' last message id %d not %d",
- mp->plugin_name, clib_net_to_host_u16 (mp->last_msg_id),
+ plugin_name, clib_net_to_host_u16 (mp->last_msg_id),
rp->last_msg_id);
}
+ vec_free (plugin_name);
}
#define foreach_rpc_api_msg \