X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibmemory%2Fmemory_shared.c;h=f44ab7c41061a1975b2b3bdbd50943c72e0d313e;hb=6595ff7f88be45d4c3f4dae09f7253b8b4ed26af;hp=0604b0a1cdfcfb3178fd9d248afec2e5ffa6820f;hpb=b7b929931a07fbb27b43d5cd105f366c3e29807e;p=vpp.git diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c index 0604b0a1cdf..f44ab7c4106 100644 --- a/src/vlibmemory/memory_shared.c +++ b/src/vlibmemory/memory_shared.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,7 @@ vl_msg_api_alloc_internal (int nbytes, int pool, int may_return_null) rv = clib_mem_alloc (nbytes); rv->q = 0; + rv->gc_mark_timestamp = 0; svm_pop_heap (oldheap); pthread_mutex_unlock (&am->vlib_rp->mutex); @@ -207,6 +209,16 @@ vl_msg_api_alloc (int nbytes) return vl_msg_api_alloc_internal (nbytes, pool, 0 /* may_return_null */ ); } +void * +vl_msg_api_alloc_zero (int nbytes) +{ + void *ret; + + ret = vl_msg_api_alloc (nbytes); + clib_memset (ret, 0, nbytes); + return ret; +} + void * vl_msg_api_alloc_or_null (int nbytes) { @@ -224,6 +236,16 @@ vl_msg_api_alloc_as_if_client (int nbytes) return vl_msg_api_alloc_internal (nbytes, 0, 0 /* may_return_null */ ); } +void * +vl_msg_api_alloc_zero_as_if_client (int nbytes) +{ + void *ret; + + ret = vl_msg_api_alloc_as_if_client (nbytes); + clib_memset (ret, 0, nbytes); + return ret; +} + void * vl_msg_api_alloc_as_if_client_or_null (int nbytes) { @@ -514,7 +536,7 @@ vl_map_shmem (const char *region_name, int is_vlib) svm_map_region_args_t _a, *a = &_a; svm_region_t *vlib_rp, *root_rp; api_main_t *am = &api_main; - int i, rv; + int i; struct timespec ts, tsrem; char *vpe_api_region_suffix = "-vpe-api"; @@ -532,9 +554,36 @@ vl_map_shmem (const char *region_name, int is_vlib) if (is_vlib == 0) { - rv = svm_region_init_chroot (am->root_path); - if (rv) - return rv; + int tfd; + u8 *api_name; + /* + * Clients wait for vpp to set up the root / API regioins + */ + if (am->root_path) + api_name = format (0, "/dev/shm/%s-%s%c", am->root_path, + region_name + 1, 0); + else + api_name = format (0, "/dev/shm%s%c", region_name, 0); + + /* Wait up to 100 seconds... */ + for (i = 0; i < 10000; i++) + { + ts.tv_sec = 0; + ts.tv_nsec = 10000 * 1000; /* 10 ms */ + while (nanosleep (&ts, &tsrem) < 0) + ts = tsrem; + tfd = open ((char *) api_name, O_RDWR); + if (tfd >= 0) + break; + } + vec_free (api_name); + if (tfd < 0) + { + clib_warning ("region init fail"); + return -2; + } + close (tfd); + svm_region_init_chroot_uid_gid (am->root_path, getuid (), getgid ()); } if (a->root_path != NULL) @@ -709,6 +758,34 @@ vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem) if (am->tx_trace && am->tx_trace->enabled) vl_msg_api_trace (am, am->tx_trace, (void *) trace[0]); + /* + * Announce a probable binary API client bug: + * some client's input queue is stuffed. + * The situation may be recoverable, or not. + */ + if (PREDICT_FALSE + (am->vl_clients /* vpp side */ && (q->cursize == q->maxsize))) + { + if (PREDICT_FALSE (am->elog_trace_api_messages)) + { + /* *INDENT-OFF* */ + ELOG_TYPE_DECLARE (e) = + { + .format = "api-client-queue-stuffed: %x%x", + .format_args = "i4i4", + }; + /* *INDENT-ON* */ + struct + { + u32 hi, low; + } *ed; + ed = ELOG_DATA (am->elog_main, e); + ed->hi = (uword) q >> 32; + ed->low = (uword) q & 0xFFFFFFFF; + clib_warning ("WARNING: client input queue at %llx is stuffed...", + q); + } + } (void) svm_queue_add (q, elem, 0 /* nowait */ ); }