ip: add support to preallocate pools 91/42191/4
authorMohsin Kazmi <[email protected]>
Mon, 10 Feb 2025 11:19:47 +0000 (11:19 +0000)
committerNeale Ranns <[email protected]>
Sat, 15 Feb 2025 03:06:12 +0000 (03:06 +0000)
Type: improvement

In certain use cases, the underlying pools expand by allocating a new,
larger pool and copying the existing elements into it. This process
can be time-consuming, leading to slower control plane configurations,
especially when a large number of elements are already present.
This patch allows users to pre-configure some of these pools through
startup.conf.
It also fixes alignment for ip4 mtrie.

Signed-off-by: Mohsin Kazmi <[email protected]>
Signed-off-by: BenoĆ®t Ganne <[email protected]>
Change-Id: Ib0f1d40e3efb8b4fce989219196c718d6834498a

src/vnet/dpo/load_balance.c
src/vnet/dpo/load_balance.h
src/vnet/fib/fib_entry.c
src/vnet/fib/fib_entry.h
src/vnet/ip/ip4_mtrie.c
src/vnet/ip/ip4_mtrie.h
src/vnet/ip/ip_init.c
src/vpp/conf/startup.conf

index 8f2a0de..f6f9392 100644 (file)
@@ -1030,6 +1030,7 @@ load_balance_module_init (void)
      * This should never be used, but just in case, stack it on a drop.
      */
     lbi = load_balance_create(1, DPO_PROTO_IP4, 0);
+    ASSERT(0 == lbi);
     load_balance_set_bucket(lbi, 0, drop_dpo_get(DPO_PROTO_IP4));
 
     load_balance_logger =
@@ -1038,6 +1039,12 @@ load_balance_module_init (void)
     load_balance_map_module_init();
 }
 
+void
+load_balance_pool_alloc (uword size)
+{
+  pool_alloc_aligned(load_balance_pool, size, CLIB_CACHE_LINE_BYTES);
+}
+
 static clib_error_t *
 load_balance_show (vlib_main_t * vm,
                    unformat_input_t * input,
index eee073f..76aa798 100644 (file)
@@ -260,5 +260,6 @@ load_balance_get_bucket_i (const load_balance_t *lb,
 }
 
 extern void load_balance_module_init(void);
+extern void load_balance_pool_alloc (uword size);
 
 #endif
index adf880b..c86941f 100644 (file)
@@ -1772,6 +1772,12 @@ fib_entry_module_init (void)
     fib_entry_track_module_init();
 }
 
+void
+fib_entry_pool_alloc (uword size)
+{
+  pool_alloc(fib_entry_pool, size);
+}
+
 fib_route_path_t *
 fib_entry_encode (fib_node_index_t fib_entry_index)
 {
index 7331f80..2c88d1e 100644 (file)
@@ -480,6 +480,7 @@ extern void fib_entry_set_flow_hash_config(fib_node_index_t fib_entry_index,
                                            flow_hash_config_t hash_config);
 
 extern void fib_entry_module_init(void);
+extern void fib_entry_pool_alloc(uword size);
 
 extern u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index);
 
index 00855f7..df70dc9 100644 (file)
@@ -190,7 +190,7 @@ ip4_mtrie_8_init (ip4_mtrie_8_t *m)
 {
   ip4_mtrie_8_ply_t *root;
 
-  pool_get (ip4_ply_pool, root);
+  pool_get_aligned (ip4_ply_pool, root, CLIB_CACHE_LINE_BYTES);
   m->root_ply = root - ip4_ply_pool;
 
   ply_8_init (root, IP4_MTRIE_LEAF_EMPTY, 0, 0);
@@ -853,13 +853,19 @@ ip4_mtrie_module_init (vlib_main_t * vm)
   clib_error_t *error = NULL;
 
   /* Burn one ply so index 0 is taken */
-  pool_get (ip4_ply_pool, p);
+  pool_get_aligned (ip4_ply_pool, p, CLIB_CACHE_LINE_BYTES);
 
   return (error);
 }
 
 VLIB_INIT_FUNCTION (ip4_mtrie_module_init);
 
+void
+ip4_mtrie_pool_alloc (uword size)
+{
+  pool_alloc_aligned (ip4_ply_pool, size, CLIB_CACHE_LINE_BYTES);
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
index 16c5247..2631f07 100644 (file)
@@ -178,6 +178,11 @@ format_function_t format_ip4_mtrie_8;
  */
 extern ip4_mtrie_8_ply_t *ip4_ply_pool;
 
+/**
+ * @brief Pre-allocate the pool of plys
+ */
+extern void ip4_mtrie_pool_alloc (uword size);
+
 /**
  * Is the leaf terminal (i.e. an LB index) or non-terminal (i.e. a PLY index)
  */
index c2490f1..cfc3644 100644 (file)
@@ -38,6 +38,9 @@
  */
 
 #include <vnet/ip/ip.h>
+#include <vnet/ip/ip4_mtrie.h>
+#include <vnet/fib/fib_entry.h>
+#include <vnet/dpo/load_balance.h>
 
 ip_main_t ip_main;
 
@@ -112,6 +115,39 @@ VLIB_INIT_FUNCTION (ip_main_init) = {
                            "flow_classify_init"),
 };
 
+static clib_error_t *
+ip_config_init (vlib_main_t *vm, unformat_input_t *input)
+{
+  uword lbsz = 0, fibentrysz = 0, mtriesz = 0;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "load-balance-pool-size %U", unformat_memory_size,
+                   &lbsz))
+       ;
+      else if (unformat (input, "fib-entry-pool-size %U", unformat_memory_size,
+                        &fibentrysz))
+       ;
+      else if (unformat (input, "ip4-mtrie-pool-size %U", unformat_memory_size,
+                        &mtriesz))
+       ;
+      else
+       return clib_error_return (0, "unknown input `%U'",
+                                 format_unformat_error, input);
+    }
+
+  if (lbsz)
+    load_balance_pool_alloc (lbsz);
+  if (fibentrysz)
+    fib_entry_pool_alloc (fibentrysz);
+  if (mtriesz)
+    ip4_mtrie_pool_alloc (mtriesz);
+
+  return 0;
+}
+
+VLIB_CONFIG_FUNCTION (ip_config_init, "l3fib");
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
index a30a15a..8e7aebd 100644 (file)
@@ -231,6 +231,18 @@ cpu {
     # update-interval <f64-seconds>, sets the segment scrape / update interval
 # }
 
+## L3 FIB
+# l3fib {
+    ## load balance pool size preallocation (expected number of objects)
+    # load-balance-pool-size 1M
+
+    ## fib entry pool size preallocation (expected number of objects)
+    # fib-entry-pool-size 1M
+
+    ## ip4 mtrie pool size preallocation (expected number of mtries)
+    # ip4-mtrie-pool-size 1K
+# }
+
 ## L2 FIB
 # l2fib {
     ## l2fib hash table size.