A Protocol Independent Hierarchical FIB (VPP-352)
[vpp.git] / vnet / vnet / adj / adj_alloc.c
similarity index 72%
rename from vnet/vnet/ip/adj_alloc.c
rename to vnet/vnet/adj/adj_alloc.c
index 3ae7a19..5cc8cf6 100644 (file)
  * limitations under the License.
  */
 
-#include <vnet/ip/adj_alloc.h>
+#include <vnet/adj/adj_alloc.h>
 #include <vnet/ip/ip.h>
 
+/*
+ * the single adj heap
+ */
+ip_adjacency_t *adj_heap;
+
 /* 
  * any operation which could cause the adj vector to be reallocated
  * must have a worker thread barrier
  */
-
 static inline int will_reallocate (ip_adjacency_t * adjs, u32 n)
 {
   uword aligned_header_bytes, new_data_bytes;
@@ -45,13 +49,14 @@ static inline int will_reallocate (ip_adjacency_t * adjs, u32 n)
 }
 
 ip_adjacency_t * 
-aa_alloc (ip_adjacency_t * adjs, ip_adjacency_t **blockp, u32 n)
+aa_alloc (void)
 {
   vlib_main_t * vm = &vlib_global_main;
-  aa_header_t * ah = aa_header (adjs);
+  aa_header_t * ah = aa_header (adj_heap);
   ip_adjacency_t * adj_block;
   u32 freelist_length;
   int need_barrier_sync = 0;
+  u32 n = 1;
   
   ASSERT(os_get_cpu_number() == 0);
   ASSERT (clib_mem_is_heap_object (_vec_find(ah)));
@@ -59,14 +64,14 @@ aa_alloc (ip_adjacency_t * adjs, ip_adjacency_t **blockp, u32 n)
   /* If we don't have a freelist of size N, fresh allocation is required */
   if (vec_len (ah->free_indices_by_size) <= n)
     {
-      if (will_reallocate (adjs, n))
+      if (will_reallocate (adj_heap, n))
         {
           need_barrier_sync = 1;
           vlib_worker_thread_barrier_sync (vm);
         }
       /* Workers wont look at the freelists... */
       vec_validate (ah->free_indices_by_size, n);
-      vec_add2_ha (adjs, adj_block, n, aa_aligned_header_bytes, 
+      vec_add2_ha (adj_heap, adj_block, n, aa_aligned_header_bytes, 
                    CLIB_CACHE_LINE_BYTES);
       if (need_barrier_sync)
         vlib_worker_thread_barrier_release (vm);
@@ -77,17 +82,17 @@ aa_alloc (ip_adjacency_t * adjs, ip_adjacency_t **blockp, u32 n)
     {
       u32 index = ah->free_indices_by_size[n][freelist_length-1];
 
-      adj_block = &adjs[index];
+      adj_block = &adj_heap[index];
       _vec_len(ah->free_indices_by_size[n]) -= 1;
       goto out;
     }
   /* Allocate a new block of size N */
-  if (will_reallocate (adjs, n))
+  if (will_reallocate (adj_heap, n))
     {
       need_barrier_sync = 1;
       vlib_worker_thread_barrier_sync (vm);
     }
-  vec_add2_ha (adjs, adj_block, n, aa_aligned_header_bytes, 
+  vec_add2_ha (adj_heap, adj_block, n, aa_aligned_header_bytes, 
                CLIB_CACHE_LINE_BYTES);
   
   if (need_barrier_sync)
@@ -95,40 +100,45 @@ aa_alloc (ip_adjacency_t * adjs, ip_adjacency_t **blockp, u32 n)
 
  out:
   memset (adj_block, 0, n * (sizeof(*adj_block)));
-  adj_block->heap_handle = adj_block - adjs;
+  adj_block->heap_handle = adj_block - adj_heap;
   adj_block->n_adj = n;
-  *blockp = adj_block;
-  return adjs;
+
+  /*
+   * the adj heap may have realloc'd. recache.
+   */
+  ip4_main.lookup_main.adjacency_heap = adj_heap;
+  ip6_main.lookup_main.adjacency_heap = adj_heap;
+
+  return (adj_block);
 }
 
-void aa_free (ip_adjacency_t * adjs, ip_adjacency_t * adj)
+void aa_free (ip_adjacency_t * adj)
 {
-  aa_header_t * ah = aa_header (adjs);
+  aa_header_t * ah = aa_header (adj_heap);
   
-  ASSERT (adjs && adj && (adj->heap_handle < vec_len (adjs)));
-  ASSERT (adj->n_adj < vec_len (ah->free_indices_by_size));
+  ASSERT (adj_heap && adj && (adj->heap_handle < vec_len (adj_heap)));
   ASSERT (adj->heap_handle != 0);
   
   vec_add1 (ah->free_indices_by_size[adj->n_adj], adj->heap_handle);
   adj->heap_handle = 0;
 }
 
-ip_adjacency_t * aa_bootstrap (ip_adjacency_t * adjs, u32 n)
+void aa_bootstrap (u32 n)
 {
   ip_adjacency_t * adj_block;
   aa_header_t * ah;
   int i;
 
-  vec_add2_ha (adjs, adj_block, n, aa_aligned_header_bytes, 
+  vec_add2_ha (adj_heap, adj_block, n, aa_aligned_header_bytes, 
                CLIB_CACHE_LINE_BYTES);
 
   memset (adj_block, 0, n * sizeof(*adj_block));
-  ah = aa_header (adjs);
+  ah = aa_header (adj_heap);
   memset (ah, 0, sizeof (*ah));
 
   vec_validate (ah->free_indices_by_size, 1);
 
-  for (i = 0 ; i < vec_len (adjs); i++)
+  for (i = 0 ; i < vec_len (adj_heap); i++)
     {
       adj_block->n_adj = 1;
       adj_block->heap_handle = ~0;
@@ -136,24 +146,23 @@ ip_adjacency_t * aa_bootstrap (ip_adjacency_t * adjs, u32 n)
       vec_add1 (ah->free_indices_by_size[1], n - (i+1));
     }
 
-  return adjs;
+  ip4_main.lookup_main.adjacency_heap = adj_heap;
+  ip6_main.lookup_main.adjacency_heap = adj_heap;
 }
 
 u8 * format_adjacency_alloc (u8 * s, va_list * args)
 {
   vnet_main_t * vnm = va_arg (*args, vnet_main_t *);
-  ip_lookup_main_t * lm = va_arg (*args, ip_lookup_main_t *);
-  ip_adjacency_t * adjs = va_arg (*args, ip_adjacency_t *);
   int verbose = va_arg (*args, int);
   ip_adjacency_t * adj;
   u32 inuse = 0, freed = 0;
   u32 on_freelist = 0;
   int i, j;
-  aa_header_t * ah = aa_header (adjs);
+  aa_header_t * ah = aa_header (adj_heap);
 
-  for (i = 0; i < vec_len (adjs); i += adj->n_adj)
+  for (i = 0; i < vec_len (adj_heap); i += adj->n_adj)
     {
-      adj = adjs + i;
+      adj = adj_heap + i;
       if ((i == 0) || adj->heap_handle)
         inuse += adj->n_adj;
       else
@@ -164,19 +173,19 @@ u8 * format_adjacency_alloc (u8 * s, va_list * args)
     {
       for (j = 0; j < vec_len(ah->free_indices_by_size[i]); j++)
         {
-          adj = adjs + ah->free_indices_by_size[i][j];
+          adj = adj_heap + ah->free_indices_by_size[i][j];
           ASSERT(adj->heap_handle == 0);
           on_freelist += adj->n_adj;
         }
     }
       
-  s = format (s, "adjs: %d total, %d in use, %d free, %d on freelists\n",
-              vec_len(adjs), inuse, freed, on_freelist);
+  s = format (s, "adj_heap: %d total, %d in use, %d free, %d on freelists\n",
+              vec_len(adj_heap), inuse, freed, on_freelist);
   if (verbose)
     {
-      for (i = 0; i < vec_len (adjs); i += adj->n_adj)
+      for (i = 0; i < vec_len (adj_heap); i += adj->n_adj)
         {
-          adj = adjs + i;
+          adj = adj_heap + i;
           if ((i == 0) || adj->heap_handle)
             {
               if (adj->n_adj > 1)
@@ -190,7 +199,7 @@ u8 * format_adjacency_alloc (u8 * s, va_list * args)
                     s = format (s, "      ");
 
                   s = format(s, "%U\n", format_ip_adjacency, 
-                         vnm, lm, i+j);
+                            vnm, i+j, FORMAT_IP_ADJACENCY_NONE);
                 }
             }
         }
@@ -200,36 +209,22 @@ u8 * format_adjacency_alloc (u8 * s, va_list * args)
 
 static clib_error_t *
 show_adjacency_alloc_command_fn (vlib_main_t * vm,
-                unformat_input_t * input,
-                vlib_cli_command_t * cmd)
+                                unformat_input_t * input,
+                                vlib_cli_command_t * cmd)
 {
   int verbose = 0;
   vnet_main_t *vnm = vnet_get_main();
-  ip_lookup_main_t *lm = 0;
-  ip_adjacency_t * adjs = 0;
-  int is_ip4 = 1;
   
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
     {
       if (unformat (input, "verbose"))
         verbose = 1;
-      else if (unformat (input, "ip4"))
-        ;
-      else if (unformat (input, "ip6"))
-        is_ip4 = 0;
       else
         return clib_error_return (0, "unknown input `%U'",
                                   format_unformat_error, input);
     }
 
-  if (is_ip4)
-      lm = &ip4_main.lookup_main;
-  else
-      lm = &ip6_main.lookup_main;
-
-  adjs = lm->adjacency_heap;
-
-  vlib_cli_output (vm, "%U", format_adjacency_alloc, vnm, lm, adjs, verbose);
+  vlib_cli_output (vm, "%U", format_adjacency_alloc, vnm, verbose);
 
   return 0;
 }