aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-01-09 15:54:00 -0500
committerDave Barach <dave@barachs.net>2017-01-09 15:54:41 -0500
commit842b9c59cc21b3e2917aaa25069fb15addf976f1 (patch)
treedff8bd1e948ac1e311bf8547ee40175b6eeace8e
parentd995c757f05f78aa759b0a65c0a7e38088e690a9 (diff)
Self-service garbage collection for the API message allocator
Change-Id: Iadc08eede15fa5978e4010bbece0232aab8b0fee Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/vlibapi/api.h3
-rw-r--r--src/vlibmemory/api.h3
-rw-r--r--src/vlibmemory/memory_shared.c21
-rw-r--r--src/vlibmemory/memory_vlib.c7
4 files changed, 30 insertions, 4 deletions
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h
index 970a0ee0157..fcb101d7dba 100644
--- a/src/vlibapi/api.h
+++ b/src/vlibapi/api.h
@@ -124,6 +124,7 @@ typedef struct
u8 *is_mp_safe;
struct ring_alloc_ *arings;
u32 ring_misses;
+ u32 garbage_collects;
u32 missing_clients;
vl_api_trace_t *rx_trace;
vl_api_trace_t *tx_trace;
@@ -212,7 +213,7 @@ typedef struct msgbuf_
{
unix_shared_memory_queue_t *q;
u32 data_len;
- u32 pad;
+ u32 gc_mark_timestamp;
u8 data[0];
} msgbuf_t;
diff --git a/src/vlibmemory/api.h b/src/vlibmemory/api.h
index 54a0a0011fd..8e44c20d4ed 100644
--- a/src/vlibmemory/api.h
+++ b/src/vlibmemory/api.h
@@ -86,6 +86,9 @@ typedef struct vl_shmem_hdr_
/* Number of messages reclaimed during application restart */
u32 restart_reclaims;
+ /* Number of garbage-collected messages */
+ u32 garbage_collects;
+
} vl_shmem_hdr_t;
#define VL_SHM_VERSION 2
diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c
index d8d3200485e..c41f32f70f9 100644
--- a/src/vlibmemory/memory_shared.c
+++ b/src/vlibmemory/memory_shared.c
@@ -95,12 +95,31 @@ vl_msg_api_alloc_internal (int nbytes, int pool, int may_return_null)
*/
if (rv->q)
{
+ u32 now = (u32) time (0);
+
+ if (PREDICT_TRUE (rv->gc_mark_timestamp == 0))
+ rv->gc_mark_timestamp = now;
+ else
+ {
+ if (now - rv->gc_mark_timestamp > 10)
+ {
+ if (CLIB_DEBUG > 0)
+ clib_warning ("garbage collect pool %d ring %d index %d",
+ pool, i, q->head);
+ shmem_hdr->garbage_collects++;
+ goto collected;
+ }
+ }
+
+
/* yes, loser; try next larger pool */
ap[i].misses++;
if (pool == 0)
pthread_mutex_unlock (&q->mutex);
continue;
}
+ collected:
+
/* OK, we have a winner */
ap[i].hits++;
/*
@@ -108,6 +127,7 @@ vl_msg_api_alloc_internal (int nbytes, int pool, int may_return_null)
* don't need to know the queue to free the item.
*/
rv->q = q;
+ rv->gc_mark_timestamp = 0;
q->head++;
if (q->head == q->maxsize)
q->head = 0;
@@ -201,6 +221,7 @@ vl_msg_api_free (void *a)
if (rv->q)
{
rv->q = 0;
+ rv->gc_mark_timestamp = 0;
return;
}
diff --git a/src/vlibmemory/memory_vlib.c b/src/vlibmemory/memory_vlib.c
index 69f35d720d3..7d21c9dd125 100644
--- a/src/vlibmemory/memory_vlib.c
+++ b/src/vlibmemory/memory_vlib.c
@@ -853,9 +853,10 @@ vl_api_ring_command (vlib_main_t * vm,
vlib_cli_output (vm, "%d ring miss fallback allocations\n",
am->ring_misses);
- vlib_cli_output (vm, "%d application restarts, %d reclaimed msgs\n",
- shmem_hdr->application_restarts,
- shmem_hdr->restart_reclaims);
+ vlib_cli_output
+ (vm, "%d application restarts, %d reclaimed msgs, %d garbage collects\n",
+ shmem_hdr->application_restarts,
+ shmem_hdr->restart_reclaims, shmem_hdr->garbage_collects);
return 0;
}