X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibmemory%2Fmemory_api.c;h=544e59ddb6949ad453a6cf8dbd63dabc4c95290a;hb=b2204671dad112e3195771854b4ef00bb388d4e6;hp=d049a62501573ec279c70c10db0dddb07727a6d6;hpb=e86a8edd3c14fb41ace2a12efd17bc7772bf623f;p=vpp.git diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c index d049a625015..544e59ddb69 100644 --- a/src/vlibmemory/memory_api.c +++ b/src/vlibmemory/memory_api.c @@ -103,6 +103,14 @@ memclnt_queue_callback (vlib_main_t * vm) break; } } + if (vec_len (vm->pending_rpc_requests)) + { + vm->queue_signal_pending = 1; + vm->api_queue_nonempty = 1; + vlib_process_signal_event (vm, vl_api_clnt_node.index, + /* event_type */ QUEUE_SIGNAL_EVENT, + /* event_data */ 0); + } } /* @@ -127,7 +135,7 @@ vl_api_memclnt_create_internal (char *name, svm_queue_t * q) *regpp = clib_mem_alloc (sizeof (vl_api_registration_t)); regp = *regpp; - memset (regp, 0, sizeof (*regp)); + clib_memset (regp, 0, sizeof (*regp)); regp->registration_type = REGISTRATION_TYPE_SHMEM; regp->vl_api_registration_pool_index = regpp - am->vl_clients; regp->vlib_rp = svm; @@ -157,6 +165,7 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) int rv = 0; void *oldheap; api_main_t *am = &api_main; + u8 *msg_table; /* * This is tortured. Maintain a vlib-address-space private @@ -193,11 +202,12 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) *regpp = clib_mem_alloc (sizeof (vl_api_registration_t)); regp = *regpp; - memset (regp, 0, sizeof (*regp)); + clib_memset (regp, 0, sizeof (*regp)); regp->registration_type = REGISTRATION_TYPE_SHMEM; regp->vl_api_registration_pool_index = regpp - am->vl_clients; regp->vlib_rp = svm; regp->shmem_hdr = am->shmem_hdr; + regp->clib_file_index = am->shmem_hdr->clib_file_index; q = regp->vl_input_queue = (svm_queue_t *) (uword) mp->input_queue; @@ -208,6 +218,11 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) am->serialized_message_table_in_shmem = vl_api_serialize_message_table (am, 0); + if (am->vlib_rp != am->vlib_primary_rp) + msg_table = vl_api_serialize_message_table (am, 0); + else + msg_table = am->serialized_message_table_in_shmem; + pthread_mutex_unlock (&svm->mutex); svm_pop_heap (oldheap); @@ -219,8 +234,7 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) am->shmem_hdr->application_restarts); rp->context = mp->context; rp->response = ntohl (rv); - rp->message_table = - pointer_to_uword (am->serialized_message_table_in_shmem); + rp->message_table = pointer_to_uword (msg_table); vl_msg_api_send_shmem (q, (u8 *) & rp); } @@ -273,7 +287,7 @@ vl_api_memclnt_delete_t_handler (vl_api_memclnt_delete_t * mp) return; } - regpp = am->vl_clients + client_index; + regpp = pool_elt_at_index (am->vl_clients, client_index); if (!pool_is_free (am->vl_clients, regpp)) { @@ -338,8 +352,9 @@ vl_api_memclnt_delete_t_handler (vl_api_memclnt_delete_t * mp) regp->vl_api_registration_pool_index); pthread_mutex_lock (&svm->mutex); oldheap = svm_push_data_heap (svm); + vec_free (regp->name); /* Poison the old registration */ - memset (regp, 0xF1, sizeof (*regp)); + clib_memset (regp, 0xF1, sizeof (*regp)); clib_mem_free (regp); pthread_mutex_unlock (&svm->mutex); svm_pop_heap (oldheap); @@ -393,7 +408,7 @@ vl_api_memclnt_keepalive_t_handler (vl_api_memclnt_keepalive_t * mp) shmem_hdr = am->shmem_hdr; rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp)); - memset (rmp, 0, sizeof (*rmp)); + clib_memset (rmp, 0, sizeof (*rmp)); rmp->_vl_msg_id = ntohs (VL_API_MEMCLNT_KEEPALIVE_REPLY); rmp->context = mp->context; vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *) & rmp); @@ -418,7 +433,7 @@ vl_mem_api_init (const char *region_name) vl_shmem_hdr_t *shm; vlib_main_t *vm = vlib_get_main (); - memset (c, 0, sizeof (*c)); + clib_memset (c, 0, sizeof (*c)); if ((rv = vl_map_shmem (region_name, 1 /* is_vlib */ )) < 0) return rv; @@ -457,6 +472,20 @@ vl_mem_api_init (const char *region_name) return 0; } +clib_error_t * +map_api_segment_init (vlib_main_t * vm) +{ + api_main_t *am = &api_main; + int rv; + + if ((rv = vl_mem_api_init (am->region_name)) < 0) + { + return clib_error_return (0, "vl_mem_api_init (%s) failed", + am->region_name); + } + return 0; +} + static void send_memclnt_keepalive (vl_api_registration_t * regp, f64 now) { @@ -492,7 +521,7 @@ send_memclnt_keepalive (vl_api_registration_t * regp, f64 now) am->shmem_hdr = regp->shmem_hdr; mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_MEMCLNT_KEEPALIVE); mp->context = mp->client_index = vl_msg_api_handle_from_index_and_epoch @@ -509,11 +538,54 @@ send_memclnt_keepalive (vl_api_registration_t * regp, f64 now) am->shmem_hdr = save_shmem_hdr; } +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) +{ + vl_api_registration_t *regp = *regpp; + if (regp) + { + /* If we haven't heard from this client recently... */ + if (regp->last_heard < (now - 10.0)) + { + if (regp->unanswered_pings == 2) + { + svm_queue_t *q; + q = regp->vl_input_queue; + if (kill (q->consumer_pid, 0) >= 0) + { + clib_warning ("REAPER: lazy binary API client '%s'", + regp->name); + regp->unanswered_pings = 0; + regp->last_heard = now; + } + else + { + clib_warning ("REAPER: binary API client '%s' died", + regp->name); + vec_add1 (*dead_indices, regpp - am->vl_clients); + } + } + else + send_memclnt_keepalive (regp, now); + } + else + regp->unanswered_pings = 0; + } + else + { + clib_warning ("NULL client registration index %d", + regpp - am->vl_clients); + vec_add1 (*confused_indices, regpp - am->vl_clients); + } +} + void vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm, f64 now) { vl_api_registration_t **regpp; - vl_api_registration_t *regp; static u32 *dead_indices; static u32 *confused_indices; @@ -521,46 +593,12 @@ vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm, f64 now) vec_reset_length (confused_indices); /* *INDENT-OFF* */ - pool_foreach (regpp, am->vl_clients, - ({ - regp = *regpp; - if (regp) - { - /* If we haven't heard from this client recently... */ - if (regp->last_heard < (now - 10.0)) - { - if (regp->unanswered_pings == 2) - { - svm_queue_t *q; - q = regp->vl_input_queue; - if (kill (q->consumer_pid, 0) >=0) - { - clib_warning ("REAPER: lazy binary API client '%s'", - regp->name); - regp->unanswered_pings = 0; - regp->last_heard = now; - } - else - { - clib_warning ("REAPER: binary API client '%s' died", - regp->name); - vec_add1(dead_indices, regpp - am->vl_clients); - } - } - else - send_memclnt_keepalive (regp, now); - } - else - regp->unanswered_pings = 0; - } - else - { - clib_warning ("NULL client registration index %d", - regpp - am->vl_clients); - vec_add1 (confused_indices, regpp - am->vl_clients); - } + pool_foreach (regpp, am->vl_clients, ({ + vl_mem_send_client_keepalive_w_reg (am, now, regpp, &dead_indices, + &confused_indices); })); /* *INDENT-ON* */ + /* This should "never happen," but if it does, fix it... */ if (PREDICT_FALSE (vec_len (confused_indices) > 0)) { @@ -628,7 +666,7 @@ vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm, f64 now) else { /* Poison the old registration */ - memset (*regpp, 0xF3, sizeof (**regpp)); + clib_memset (*regpp, 0xF3, sizeof (**regpp)); clib_mem_free (*regpp); } /* no dangling references, please */ @@ -673,6 +711,32 @@ vl_mem_api_handle_msg_main (vlib_main_t * vm, vlib_node_runtime_t * node) am->shmem_hdr->vl_input_queue); } +int +vl_mem_api_handle_rpc (vlib_main_t * vm, vlib_node_runtime_t * node) +{ + api_main_t *am = &api_main; + int i; + uword *tmp, mp; + + /* + * Swap pending and processing vectors, then process the RPCs + * Avoid deadlock conditions by construction. + */ + clib_spinlock_lock_if_init (&vm->pending_rpc_lock); + tmp = vm->processing_rpc_requests; + vec_reset_length (tmp); + vm->processing_rpc_requests = vm->pending_rpc_requests; + vm->pending_rpc_requests = tmp; + clib_spinlock_unlock_if_init (&vm->pending_rpc_lock); + + 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, (void *) mp, vm, node); + } + return 0; +} + int vl_mem_api_handle_msg_private (vlib_main_t * vm, vlib_node_runtime_t * node, u32 reg_index) @@ -702,24 +766,26 @@ vl_mem_api_client_index_to_registration (u32 handle) vl_api_registration_t **regpp; vl_api_registration_t *regp; api_main_t *am = &api_main; + vl_shmem_hdr_t *shmem_hdr; u32 index; index = vl_msg_api_handle_get_index (handle); - if ((am->shmem_hdr->application_restarts & VL_API_EPOCH_MASK) - != vl_msg_api_handle_get_epoch (handle)) + regpp = am->vl_clients + index; + + if (pool_is_free (am->vl_clients, regpp)) { vl_msg_api_increment_missing_client_counter (); return 0; } + regp = *regpp; - regpp = am->vl_clients + index; - - if (pool_is_free (am->vl_clients, regpp)) + shmem_hdr = (vl_shmem_hdr_t *) regp->shmem_hdr; + if (!vl_msg_api_handle_is_valid (handle, shmem_hdr->application_restarts)) { vl_msg_api_increment_missing_client_counter (); return 0; } - regp = *regpp; + return (regp); } @@ -866,12 +932,34 @@ vlibmemory_init (vlib_main_t * vm) api_main_t *am = &api_main; svm_map_region_args_t _a, *a = &_a; clib_error_t *error; + u8 *remove_path1, *remove_path2; + + /* + * By popular request / to avoid support fires, remove any old api segment + * files Right Here. + */ + if (am->root_path == 0) + { + remove_path1 = format (0, "/dev/shm/global_vm%c", 0); + remove_path2 = format (0, "/dev/shm/vpe-api%c", 0); + } + else + { + remove_path1 = format (0, "/dev/shm/%s-global_vm%c", am->root_path, 0); + remove_path2 = format (0, "/dev/shm/%s-vpe-api%c", am->root_path, 0); + } + + (void) unlink ((char *) remove_path1); + (void) unlink ((char *) remove_path2); - memset (a, 0, sizeof (*a)); + vec_free (remove_path1); + vec_free (remove_path2); + + clib_memset (a, 0, sizeof (*a)); a->root_path = am->root_path; a->name = SVM_GLOBAL_REGION_NAME; a->baseva = (am->global_baseva != 0) ? - am->global_baseva : SVM_GLOBAL_REGION_BASEVA; + am->global_baseva : +svm_get_global_region_base_va (); a->size = (am->global_size != 0) ? am->global_size : SVM_GLOBAL_REGION_SIZE; a->flags = SVM_FLAGS_NODATA; a->uid = am->api_uid; @@ -887,8 +975,6 @@ vlibmemory_init (vlib_main_t * vm) return error; } -VLIB_INIT_FUNCTION (vlibmemory_init); - void vl_set_memory_region_name (const char *name) {