Self-service garbage collection for the API message allocator 12/4612/1
authorDave Barach <dave@barachs.net>
Mon, 9 Jan 2017 20:54:00 +0000 (15:54 -0500)
committerDave Barach <dave@barachs.net>
Mon, 9 Jan 2017 20:54:41 +0000 (15:54 -0500)
Change-Id: Iadc08eede15fa5978e4010bbece0232aab8b0fee
Signed-off-by: Dave Barach <dave@barachs.net>
src/vlibapi/api.h
src/vlibmemory/api.h
src/vlibmemory/memory_shared.c
src/vlibmemory/memory_vlib.c

index 970a0ee..fcb101d 100644 (file)
@@ -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;
 
index 54a0a00..8e44c20 100644 (file)
@@ -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
index d8d3200..c41f32f 100644 (file)
@@ -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;
     }
 
index 69f35d7..7d21c9d 100644 (file)
@@ -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;
 }