* 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;
}
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)));
/* 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);
{
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)
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;
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
{
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)
s = format (s, " ");
s = format(s, "%U\n", format_ip_adjacency,
- vnm, lm, i+j);
+ vnm, i+j, FORMAT_IP_ADJACENCY_NONE);
}
}
}
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;
}