aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlib/init.c
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2019-06-03 19:48:22 -0400
committerDamjan Marion <dmarion@me.com>2019-06-04 13:04:42 +0000
commitc602b384ac022f70690a3a7c711149f7cb63ad12 (patch)
treecad51d5702502d35c714b3a003d000ffe7aae4db /src/vlib/init.c
parentc424de75e561b2197d29812b3900db58a06096d7 (diff)
sort worker-thread init functions in advance
Otherwise, all N worker threads try to sort the list at the same time: a good way to have a bad day. This approach performs *far* better than maintaing order by adding a spin-lock. By direct measurement w/ elog + g2: 11 threads execute the per-thread init function list in 22us, vs. 50ms with a CLIB_PAUSE() enabled spin-lock. Change-Id: I1745f2a213c0561260139a60114dcb981e0c64e5 Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vlib/init.c')
-rw-r--r--src/vlib/init.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/vlib/init.c b/src/vlib/init.c
index 8010e9e97cd..135f9d582e9 100644
--- a/src/vlib/init.c
+++ b/src/vlib/init.c
@@ -72,7 +72,7 @@ comma_split (u8 * s, u8 ** a, u8 ** b)
* @returns 0 on success, otherwise a clib_error_t *.
*/
-static clib_error_t *init_exit_function_sort
+clib_error_t *vlib_sort_init_exit_functions
(_vlib_init_function_list_elt_t ** head)
{
uword *index_by_name;
@@ -329,15 +329,15 @@ again:
* A and B - and it leads to hugely annoying debugging exercises.
*/
-clib_error_t *
-vlib_call_init_exit_functions (vlib_main_t * vm,
- _vlib_init_function_list_elt_t ** headp,
- int call_once)
+static inline clib_error_t *
+call_init_exit_functions_internal (vlib_main_t * vm,
+ _vlib_init_function_list_elt_t ** headp,
+ int call_once, int do_sort)
{
clib_error_t *error = 0;
_vlib_init_function_list_elt_t *i;
- if ((error = init_exit_function_sort (headp)))
+ if (do_sort && (error = vlib_sort_init_exit_functions (headp)))
return (error);
i = *headp;
@@ -357,6 +357,24 @@ vlib_call_init_exit_functions (vlib_main_t * vm,
}
clib_error_t *
+vlib_call_init_exit_functions (vlib_main_t * vm,
+ _vlib_init_function_list_elt_t ** headp,
+ int call_once)
+{
+ return call_init_exit_functions_internal (vm, headp, call_once,
+ 1 /* do_sort */ );
+}
+
+clib_error_t *
+vlib_call_init_exit_functions_no_sort (vlib_main_t * vm,
+ _vlib_init_function_list_elt_t **
+ headp, int call_once)
+{
+ return call_init_exit_functions_internal (vm, headp, call_once,
+ 0 /* do_sort */ );
+}
+
+clib_error_t *
vlib_call_all_init_functions (vlib_main_t * vm)
{
/* Call dummy functions to make sure purely static modules are