From 7f9256e31c13fdfb640eff9d7775bc50b4396543 Mon Sep 17 00:00:00 2001 From: Benoît Ganne Date: Fri, 4 Mar 2022 17:17:04 +0100 Subject: api: better segregate client and server code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - move memory and server specific vl_msg_api_handler_with_vm_node() to memory server code only - keep api_global_main static Apart from being cleaner, this also helps avoiding symbols conflict when both client and server libs are loaded in the same process, as is done by the prom plugin. Those symbols conflict confuse ASan and can be nasty to debug. Type: improvement Change-Id: Iaf58596cc753ad8d3fedd8d65c4bf480ac129c2c Signed-off-by: Benoît Ganne --- src/vlibmemory/CMakeLists.txt | 2 - src/vlibmemory/memory_api.c | 147 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 5 deletions(-) (limited to 'src/vlibmemory') diff --git a/src/vlibmemory/CMakeLists.txt b/src/vlibmemory/CMakeLists.txt index 488a0d7b827..d14e9cad954 100644 --- a/src/vlibmemory/CMakeLists.txt +++ b/src/vlibmemory/CMakeLists.txt @@ -15,8 +15,6 @@ add_vpp_library (vlibmemory SOURCES memory_api.c memory_shared.c - memory_client.c - socket_client.c socket_api.c memclnt_api.c vlib_api_cli.c diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c index 6c066a152f4..a16110f2fa1 100644 --- a/src/vlibmemory/memory_api.c +++ b/src/vlibmemory/memory_api.c @@ -674,6 +674,147 @@ vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm, f64 now) } } +void (*vl_mem_api_fuzz_hook) (u16, void *); + +/* This is only to be called from a vlib/vnet app */ +static void +vl_mem_api_handler_with_vm_node (api_main_t *am, svm_region_t *vlib_rp, + void *the_msg, vlib_main_t *vm, + vlib_node_runtime_t *node, u8 is_private) +{ + u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); + u8 *(*handler) (void *, void *, void *); + u8 *(*print_fp) (void *, void *); + svm_region_t *old_vlib_rp; + void *save_shmem_hdr; + int is_mp_safe = 1; + + if (PREDICT_FALSE (am->elog_trace_api_messages)) + { + ELOG_TYPE_DECLARE (e) = { + .format = "api-msg: %s", + .format_args = "T4", + }; + struct + { + u32 c; + } * ed; + ed = ELOG_DATA (am->elog_main, e); + if (id < vec_len (am->msg_names) && am->msg_names[id]) + ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); + else + ed->c = elog_string (am->elog_main, "BOGUS"); + } + + if (id < vec_len (am->msg_handlers) && am->msg_handlers[id]) + { + handler = (void *) am->msg_handlers[id]; + + if (PREDICT_FALSE (am->rx_trace && am->rx_trace->enabled)) + vl_msg_api_trace (am, am->rx_trace, the_msg); + + if (PREDICT_FALSE (am->msg_print_flag)) + { + fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]); + print_fp = (void *) am->msg_print_handlers[id]; + if (print_fp == 0) + { + fformat (stdout, " [no registered print fn for msg %d]\n", id); + } + else + { + (*print_fp) (the_msg, vm); + } + } + is_mp_safe = am->is_mp_safe[id]; + + if (!is_mp_safe) + { + vl_msg_api_barrier_trace_context (am->msg_names[id]); + vl_msg_api_barrier_sync (); + } + if (is_private) + { + old_vlib_rp = am->vlib_rp; + save_shmem_hdr = am->shmem_hdr; + am->vlib_rp = vlib_rp; + am->shmem_hdr = (void *) vlib_rp->user_ctx; + } + + if (PREDICT_FALSE (vl_mem_api_fuzz_hook != 0)) + (*vl_mem_api_fuzz_hook) (id, the_msg); + + if (am->is_autoendian[id]) + { + void (*endian_fp) (void *); + endian_fp = am->msg_endian_handlers[id]; + (*endian_fp) (the_msg); + } + if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0)) + clib_call_callbacks (am->perf_counter_cbs, am, id, 0 /* before */); + + (*handler) (the_msg, vm, node); + + if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0)) + clib_call_callbacks (am->perf_counter_cbs, am, id, 1 /* after */); + if (is_private) + { + am->vlib_rp = old_vlib_rp; + am->shmem_hdr = save_shmem_hdr; + } + if (!is_mp_safe) + vl_msg_api_barrier_release (); + } + else + { + clib_warning ("no handler for msg id %d", id); + } + + /* + * Special-case, so we can e.g. bounce messages off the vnet + * main thread without copying them... + */ + if (id >= vec_len (am->message_bounce) || !(am->message_bounce[id])) + { + if (is_private) + { + old_vlib_rp = am->vlib_rp; + save_shmem_hdr = am->shmem_hdr; + am->vlib_rp = vlib_rp; + am->shmem_hdr = (void *) vlib_rp->user_ctx; + } + vl_msg_api_free (the_msg); + if (is_private) + { + am->vlib_rp = old_vlib_rp; + am->shmem_hdr = save_shmem_hdr; + } + } + + if (PREDICT_FALSE (am->elog_trace_api_messages)) + { + ELOG_TYPE_DECLARE (e) = { .format = "api-msg-done(%s): %s", + .format_args = "t4T4", + .n_enum_strings = 2, + .enum_strings = { + "barrier", + "mp-safe", + } }; + + struct + { + u32 barrier; + u32 c; + } * ed; + ed = ELOG_DATA (am->elog_main, e); + if (id < vec_len (am->msg_names) && am->msg_names[id]) + ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); + else + ed->c = elog_string (am->elog_main, "BOGUS"); + ed->barrier = is_mp_safe; + } +} + static inline int void_mem_api_handle_msg_i (api_main_t * am, svm_region_t * vlib_rp, vlib_main_t * vm, vlib_node_runtime_t * node, @@ -687,7 +828,7 @@ void_mem_api_handle_msg_i (api_main_t * am, svm_region_t * vlib_rp, if (!svm_queue_sub2 (q, (u8 *) & mp)) { VL_MSG_API_UNPOISON ((void *) mp); - vl_msg_api_handler_with_vm_node (am, vlib_rp, (void *) mp, vm, node, + vl_mem_api_handler_with_vm_node (am, vlib_rp, (void *) mp, vm, node, is_private); return 0; } @@ -737,8 +878,8 @@ vl_mem_api_handle_rpc (vlib_main_t * vm, vlib_node_runtime_t * node) for (i = 0; i < vec_len (vm->processing_rpc_requests); i++) { mp = vm->processing_rpc_requests[i]; - vl_msg_api_handler_with_vm_node (am, am->vlib_rp, (void *) mp, vm, - node, 0 /* is_private */ ); + vl_mem_api_handler_with_vm_node (am, am->vlib_rp, (void *) mp, vm, + node, 0 /* is_private */); } vl_msg_api_barrier_release (); } -- cgit 1.2.3-korg