X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibmemory%2Fmemory_client.c;h=54bc8d8f85941f92d8b868eab590d0ebba922b3d;hb=9b7e8acf792cced80e6775bc5668d9db415cdb46;hp=d002845a00c4afa60f199ff55bbf61332c3c4129;hpb=c560789ca85b2325072ef1a209d4b1012dfe07bd;p=vpp.git diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c index d002845a00c..54bc8d8f859 100644 --- a/src/vlibmemory/memory_client.c +++ b/src/vlibmemory/memory_client.c @@ -24,6 +24,7 @@ #include #include #include +#include /* A hack. vl_client_get_first_plugin_msg_id depends on it */ #include @@ -38,58 +39,44 @@ #include #undef vl_endianfun +#define vl_calcsizefun +#include +#undef vl_calcsizefun + /* instantiate all the print functions we know about */ #define vl_print(handle, ...) clib_warning (__VA_ARGS__) #define vl_printfun #include #undef vl_printfun -typedef struct -{ - u8 rx_thread_jmpbuf_valid; - u8 connected_to_vlib; - jmp_buf rx_thread_jmpbuf; - pthread_t rx_thread_handle; - /* Plugin message base lookup scheme */ - volatile u8 first_msg_id_reply_ready; - u16 first_msg_id_reply; -} memory_client_main_t; - memory_client_main_t memory_client_main; +__thread memory_client_main_t *my_memory_client_main = &memory_client_main; + +typedef struct rx_thread_fn_arg +{ + api_main_t *am; + memory_client_main_t *mm; +} rx_thread_fn_arg_t; static void * rx_thread_fn (void *arg) { + rx_thread_fn_arg_t *a = (rx_thread_fn_arg_t *) arg; + memory_client_main_t *mm; svm_queue_t *q; - memory_client_main_t *mm = &memory_client_main; - api_main_t *am = &api_main; - int i; - q = am->vl_input_queue; + vlibapi_set_main (a->am); + vlibapi_set_memory_client_main (a->mm); + free (a); + + mm = vlibapi_get_memory_client_main (); + q = vlibapi_get_main ()->vl_input_queue; /* So we can make the rx thread terminate cleanly */ if (setjmp (mm->rx_thread_jmpbuf) == 0) { mm->rx_thread_jmpbuf_valid = 1; - /* - * Find an unused slot in the per-cpu-mheaps array, - * and grab it for this thread. We need to be able to - * push/pop the thread heap without affecting other thread(s). - */ - if (__os_thread_index == 0) - { - for (i = 0; i < ARRAY_LEN (clib_per_cpu_mheaps); i++) - { - if (clib_per_cpu_mheaps[i] == 0) - { - /* Copy the main thread mheap pointer */ - clib_per_cpu_mheaps[i] = clib_per_cpu_mheaps[0]; - __os_thread_index = i; - break; - } - } - ASSERT (__os_thread_index > 0); - } + clib_mem_set_thread_index (); while (1) vl_msg_api_queue_handler (q); } @@ -99,7 +86,7 @@ rx_thread_fn (void *arg) static void vl_api_rx_thread_exit_t_handler (vl_api_rx_thread_exit_t * mp) { - memory_client_main_t *mm = &memory_client_main; + memory_client_main_t *mm = vlibapi_get_memory_client_main (); if (mm->rx_thread_jmpbuf_valid) longjmp (mm->rx_thread_jmpbuf, 1); } @@ -107,7 +94,7 @@ vl_api_rx_thread_exit_t_handler (vl_api_rx_thread_exit_t * mp) static void vl_api_name_and_crc_free (void) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); int i; u8 **keys = 0; hash_pair_t *hp; @@ -127,11 +114,18 @@ vl_api_name_and_crc_free (void) hash_free (am->msg_index_by_name_and_crc); } +CLIB_NOSANITIZE_ADDR static void +VL_API_VEC_UNPOISON (const void *v) +{ + const vec_header_t *vh = &((vec_header_t *) v)[-1]; + CLIB_MEM_UNPOISON (vh, sizeof (*vh) + vec_len (v)); +} + static void vl_api_memclnt_create_reply_t_handler (vl_api_memclnt_create_reply_t * mp) { serialize_main_t _sm, *sm = &_sm; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u8 *tblv; u32 nmsgs; int i; @@ -151,6 +145,8 @@ vl_api_memclnt_create_reply_t_handler (vl_api_memclnt_create_reply_t * mp) unserialize_open_data (sm, tblv, vec_len (tblv)); unserialize_integer (sm, &nmsgs, sizeof (u32)); + VL_API_VEC_UNPOISON (tblv); + for (i = 0; i < nmsgs; i++) { msg_index = unserialize_likely_small_unsigned_integer (sm); @@ -168,14 +164,13 @@ void vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem); int vl_client_connect (const char *name, int ctx_quota, int input_queue_size) { - svm_region_t *svm; vl_api_memclnt_create_t *mp; vl_api_memclnt_create_reply_t *rp; svm_queue_t *vl_input_queue; vl_shmem_hdr_t *shmem_hdr; int rv = 0; void *oldheap; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); if (am->my_registration) { @@ -189,7 +184,6 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) return -1; } - svm = am->vlib_rp; shmem_hdr = am->shmem_hdr; if (shmem_hdr == 0 || shmem_hdr->vl_input_queue == 0) @@ -198,12 +192,13 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) return -1; } - pthread_mutex_lock (&svm->mutex); - oldheap = svm_push_data_heap (svm); + CLIB_MEM_UNPOISON (shmem_hdr, sizeof (*shmem_hdr)); + VL_MSG_API_SVM_QUEUE_UNPOISON (shmem_hdr->vl_input_queue); + + oldheap = vl_msg_push_heap (); vl_input_queue = svm_queue_alloc_and_init (input_queue_size, sizeof (uword), getpid ()); - svm_pop_heap (oldheap); - pthread_mutex_unlock (&svm->mutex); + vl_msg_pop_heap (oldheap); am->my_client_index = ~0; am->my_registration = 0; @@ -241,6 +236,7 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) return -1; read_one_msg: + VL_MSG_API_UNPOISON (rp); if (ntohs (rp->_vl_msg_id) != VL_API_MEMCLNT_CREATE_REPLY) { clib_warning ("unexpected reply: id %d", ntohs (rp->_vl_msg_id)); @@ -248,7 +244,8 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) } rv = clib_net_to_host_u32 (rp->response); - vl_msg_api_handler ((void *) rp); + msgbuf_t *msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data)); + vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len)); break; } return (rv); @@ -258,13 +255,11 @@ static void vl_api_memclnt_delete_reply_t_handler (vl_api_memclnt_delete_reply_t * mp) { void *oldheap; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); - pthread_mutex_lock (&am->vlib_rp->mutex); - oldheap = svm_push_data_heap (am->vlib_rp); + oldheap = vl_msg_push_heap (); svm_queue_free (am->vl_input_queue); - pthread_mutex_unlock (&am->vlib_rp->mutex); - svm_pop_heap (oldheap); + vl_msg_pop_heap (oldheap); am->my_client_index = ~0; am->my_registration = 0; @@ -276,7 +271,7 @@ vl_client_send_disconnect (u8 do_cleanup) { vl_api_memclnt_delete_t *mp; vl_shmem_hdr_t *shmem_hdr; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); ASSERT (am->vlib_rp); shmem_hdr = am->shmem_hdr; @@ -297,8 +292,9 @@ vl_client_disconnect (void) { vl_api_memclnt_delete_reply_t *rp; svm_queue_t *vl_input_queue; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); time_t begin; + msgbuf_t *msgbuf; vl_input_queue = am->vl_input_queue; vl_client_send_disconnect (0 /* wait for reply */ ); @@ -325,14 +321,18 @@ vl_client_disconnect (void) if (svm_queue_sub (vl_input_queue, (u8 *) & rp, SVM_Q_NOWAIT, 0) < 0) continue; + VL_MSG_API_UNPOISON (rp); + /* drain the queue */ if (ntohs (rp->_vl_msg_id) != VL_API_MEMCLNT_DELETE_REPLY) { clib_warning ("queue drain: %d", ntohs (rp->_vl_msg_id)); - vl_msg_api_handler ((void *) rp); + msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data)); + vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len)); continue; } - vl_msg_api_handler ((void *) rp); + msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data)); + vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len)); break; } @@ -351,7 +351,7 @@ vl_api_memclnt_keepalive_t_handler (vl_api_memclnt_keepalive_t * mp) api_main_t *am; vl_shmem_hdr_t *shmem_hdr; - am = &api_main; + am = vlibapi_get_main (); shmem_hdr = am->shmem_hdr; rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp)); @@ -370,14 +370,14 @@ _(MEMCLNT_KEEPALIVE, memclnt_keepalive) void vl_client_install_client_message_handlers (void) { - -#define _(N,n) \ - vl_msg_api_set_handlers(VL_API_##N, #n, \ - vl_api_##n##_t_handler, \ - noop_handler, \ - vl_api_##n##_t_endian, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 1); + api_main_t *am = vlibapi_get_main (); +#define _(N, n) \ + vl_msg_api_set_handlers ( \ + VL_API_##N, #n, vl_api_##n##_t_handler, noop_handler, \ + vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \ + vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \ + vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); \ + am->api_trace_cfg[VL_API_##N].replay_enable = 0; foreach_api_msg; #undef _ } @@ -403,16 +403,18 @@ vl_client_api_unmap (void) u8 vl_mem_client_is_connected (void) { - return (memory_client_main.connected_to_vlib != 0); + return (my_memory_client_main->connected_to_vlib != 0); } static int connect_to_vlib_internal (const char *svm_name, const char *client_name, - int rx_queue_size, int want_pthread, int do_map) + int rx_queue_size, void *(*thread_fn) (void *), + void *thread_fn_arg, int do_map) { int rv = 0; - memory_client_main_t *mm = &memory_client_main; + memory_client_main_t *mm = vlibapi_get_memory_client_main (); + api_main_t *am = vlibapi_get_main (); if (do_map && (rv = vl_client_api_map (svm_name))) { @@ -429,12 +431,28 @@ connect_to_vlib_internal (const char *svm_name, /* Start the rx queue thread */ - if (want_pthread) + if (thread_fn) { + if (thread_fn == rx_thread_fn) + { + rx_thread_fn_arg_t *arg; + arg = malloc (sizeof (*arg)); + arg->am = vlibapi_get_main (); + arg->mm = vlibapi_get_memory_client_main (); + thread_fn_arg = (void *) arg; + } + rv = pthread_create (&mm->rx_thread_handle, - NULL /*attr */ , rx_thread_fn, 0); + NULL /*attr */ , thread_fn, thread_fn_arg); if (rv) - clib_warning ("pthread_create returned %d", rv); + { + clib_warning ("pthread_create returned %d", rv); + am->rx_thread_handle = 0; + } + else + { + am->rx_thread_handle = mm->rx_thread_handle; + } } mm->connected_to_vlib = 1; @@ -446,7 +464,7 @@ vl_client_connect_to_vlib (const char *svm_name, const char *client_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 1 /* want pthread */ , + rx_thread_fn, 0 /* thread fn arg */ , 1 /* do map */ ); } @@ -456,7 +474,8 @@ vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 0 /* want pthread */ , + 0 /* no rx_thread_fn */ , + 0 /* no thread fn arg */ , 1 /* do map */ ); } @@ -465,7 +484,7 @@ vl_client_connect_to_vlib_no_map (const char *svm_name, const char *client_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 1 /* want pthread */ , + rx_thread_fn, 0 /* no thread fn arg */ , 0 /* dont map */ ); } @@ -475,15 +494,27 @@ vl_client_connect_to_vlib_no_rx_pthread_no_map (const char *svm_name, int rx_queue_size) { return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, - 0 /* want pthread */ , + 0 /* no thread_fn */ , + 0 /* no thread fn arg */ , 0 /* dont map */ ); } +int +vl_client_connect_to_vlib_thread_fn (const char *svm_name, + const char *client_name, + int rx_queue_size, + void *(*thread_fn) (void *), void *arg) +{ + return connect_to_vlib_internal (svm_name, client_name, rx_queue_size, + thread_fn, arg, 1 /* do map */ ); +} + + static void disconnect_from_vlib_internal (u8 do_unmap) { - memory_client_main_t *mm = &memory_client_main; - api_main_t *am = &api_main; + memory_client_main_t *mm = vlibapi_get_memory_client_main (); + api_main_t *am = vlibapi_get_main (); uword junk; if (mm->rx_thread_jmpbuf_valid) @@ -518,7 +549,7 @@ vl_client_disconnect_from_vlib_no_unmap (void) static void vl_api_get_first_msg_id_reply_t_handler (vl_api_get_first_msg_id_reply_t * mp) { - memory_client_main_t *mm = &memory_client_main; + memory_client_main_t *mm = vlibapi_get_memory_client_main (); i32 retval = ntohl (mp->retval); mm->first_msg_id_reply = (retval >= 0) ? ntohs (mp->first_msg_id) : ~0; @@ -529,8 +560,8 @@ u16 vl_client_get_first_plugin_msg_id (const char *plugin_name) { vl_api_get_first_msg_id_t *mp; - api_main_t *am = &api_main; - memory_client_main_t *mm = &memory_client_main; + api_main_t *am = vlibapi_get_main (); + memory_client_main_t *mm = vlibapi_get_memory_client_main (); f64 timeout; void *old_handler; clib_time_t clib_time; @@ -546,6 +577,11 @@ vl_client_get_first_plugin_msg_id (const char *plugin_name) old_handler = am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY]; am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = (void *) vl_api_get_first_msg_id_reply_t_handler; + if (!am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY]) + { + am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY] = + (uword (*) (void *)) vl_api_get_first_msg_id_reply_t_calc_size; + } /* Ask the data-plane for the message-ID base of the indicated plugin */ mm->first_msg_id_reply_ready = 0;