diff options
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/main.c | 3 | ||||
-rw-r--r-- | src/vlib/node.c | 118 | ||||
-rw-r--r-- | src/vlib/node.h | 56 | ||||
-rw-r--r-- | src/vlib/node_cli.c | 47 | ||||
-rw-r--r-- | src/vlib/node_format.c | 21 | ||||
-rw-r--r-- | src/vlib/node_funcs.h | 10 | ||||
-rw-r--r-- | src/vlib/node_init.c | 156 |
7 files changed, 218 insertions, 193 deletions
diff --git a/src/vlib/main.c b/src/vlib/main.c index 111941ce90a..02fdc89ad99 100644 --- a/src/vlib/main.c +++ b/src/vlib/main.c @@ -1962,6 +1962,9 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input) goto done; } + /* Register node ifunction variants */ + vlib_register_all_node_march_variants (vm); + /* Register static nodes so that init functions may use them. */ vlib_register_all_static_nodes (vm); diff --git a/src/vlib/node.c b/src/vlib/node.c index 25e249bdda9..618baecfde0 100644 --- a/src/vlib/node.c +++ b/src/vlib/node.c @@ -290,6 +290,43 @@ node_elog_init (vlib_main_t * vm, uword ni) #define STACK_ALIGN CLIB_CACHE_LINE_BYTES #endif +vlib_node_function_t * +vlib_node_get_preferred_node_fn_variant (vlib_main_t *vm, + vlib_node_fn_registration_t *regs) +{ + vlib_node_main_t *nm = &vm->node_main; + vlib_node_fn_registration_t *r; + vlib_node_fn_variant_t *v; + vlib_node_function_t *fn = 0; + int priority = -1; + + if (nm->node_fn_default_march_variant != ~0) + { + r = regs; + while (r) + { + if (r->march_variant == nm->node_fn_default_march_variant) + return r->function; + r = r->next_registration; + } + } + + r = regs; + while (r) + { + v = vec_elt_at_index (nm->variants, r->march_variant); + if (v->priority > priority) + { + priority = v->priority; + fn = r->function; + } + r = r->next_registration; + } + + ASSERT (fn); + return fn; +} + static void register_node (vlib_main_t * vm, vlib_node_registration_t * r) { @@ -306,22 +343,12 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) if (r->node_fn_registrations) { - vlib_node_fn_registration_t *fnr = r->node_fn_registrations; - int priority = -1; - /* to avoid confusion, please remove ".function " statiement from CLIB_NODE_REGISTRATION() if using function function candidates */ ASSERT (r->function == 0); - while (fnr) - { - if (fnr->priority > priority) - { - priority = fnr->priority; - r->function = fnr->function; - } - fnr = fnr->next_registration; - } + r->function = + vlib_node_get_preferred_node_fn_variant (vm, r->node_fn_registrations); } ASSERT (r->function != 0); @@ -483,6 +510,7 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) vec_free (n->runtime_data); } +#undef _ } /* Register new packet processing node. */ @@ -507,6 +535,40 @@ null_node_fn (vlib_main_t * vm, } void +vlib_register_all_node_march_variants (vlib_main_t *vm) +{ + vlib_node_main_t *nm = &vm->node_main; + vlib_node_fn_variant_t *v; + int prio = -1; + + nm->node_fn_default_march_variant = ~0; + ASSERT (nm->variants == 0); + vec_add2 (nm->variants, v, 1); + v->desc = v->suffix = "default"; + v->index = CLIB_MARCH_VARIANT_TYPE; + +#define _(s, n) \ + vec_add2 (nm->variants, v, 1); \ + v->suffix = #s; \ + v->index = CLIB_MARCH_VARIANT_TYPE_##s; \ + v->priority = clib_cpu_march_priority_##s (); \ + v->desc = n; + + foreach_march_variant; +#undef _ + + nm->node_fn_march_variant_by_suffix = hash_create_string (0, sizeof (u32)); + + vec_foreach (v, nm->variants) + { + ASSERT (v->index == v - nm->variants); + hash_set (nm->node_fn_march_variant_by_suffix, v->suffix, v->index); + if (v->priority > prio) + prio = v->priority; + } +} + +void vlib_register_all_static_nodes (vlib_main_t * vm) { vlib_node_registration_t *r; @@ -755,6 +817,38 @@ vlib_process_create (vlib_main_t * vm, char *name, return (r.index); } +int +vlib_node_set_march_variant (vlib_main_t *vm, u32 node_index, + clib_march_variant_type_t march_variant) +{ + vlib_node_fn_registration_t *fnr; + vlib_node_fn_variant_t *v; + vlib_node_t *n = vlib_get_node (vm, node_index); + + if (n->node_fn_registrations == 0) + return -1; + + fnr = n->node_fn_registrations; + v = vec_elt_at_index (vm->node_main.variants, march_variant); + + while (fnr) + { + if (fnr->march_variant == v->index) + { + n->function = fnr->function; + + for (int i = 0; i < vec_len (vlib_mains); i++) + { + vlib_node_runtime_t *nrt; + nrt = vlib_node_get_runtime (vlib_mains[i], n->index); + nrt->function = fnr->function; + } + return 0; + } + fnr = fnr->next_registration; + } + return -1; +} /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vlib/node.h b/src/vlib/node.h index 0c815eaa4d2..9a3bb8370af 100644 --- a/src/vlib/node.h +++ b/src/vlib/node.h @@ -89,9 +89,8 @@ typedef enum typedef struct _vlib_node_fn_registration { vlib_node_function_t *function; - int priority; + clib_march_variant_type_t march_variant; struct _vlib_node_fn_registration *next_registration; - char *name; } vlib_node_fn_registration_t; typedef struct _vlib_node_registration @@ -200,24 +199,24 @@ static __clib_unused vlib_node_registration_t __clib_unused_##x #define CLIB_MARCH_VARIANT_STR _CLIB_MARCH_VARIANT_STR(CLIB_MARCH_VARIANT) #endif -#define VLIB_NODE_FN(node) \ -uword CLIB_MARCH_SFX (node##_fn)(); \ -static vlib_node_fn_registration_t \ - CLIB_MARCH_SFX(node##_fn_registration) = \ - { .function = &CLIB_MARCH_SFX (node##_fn), }; \ - \ -static void __clib_constructor \ -CLIB_MARCH_SFX (node##_multiarch_register) (void) \ -{ \ - extern vlib_node_registration_t node; \ - vlib_node_fn_registration_t *r; \ - r = & CLIB_MARCH_SFX (node##_fn_registration); \ - r->priority = CLIB_MARCH_FN_PRIORITY(); \ - r->name = CLIB_MARCH_VARIANT_STR; \ - r->next_registration = node.node_fn_registrations; \ - node.node_fn_registrations = r; \ -} \ -uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn) +#define VLIB_NODE_FN(node) \ + uword CLIB_MARCH_SFX (node##_fn) (); \ + static vlib_node_fn_registration_t CLIB_MARCH_SFX ( \ + node##_fn_registration) = { \ + .function = &CLIB_MARCH_SFX (node##_fn), \ + }; \ + \ + static void __clib_constructor CLIB_MARCH_SFX (node##_multiarch_register) ( \ + void) \ + { \ + extern vlib_node_registration_t node; \ + vlib_node_fn_registration_t *r; \ + r = &CLIB_MARCH_SFX (node##_fn_registration); \ + r->march_variant = CLIB_MARCH_SFX (CLIB_MARCH_VARIANT_TYPE); \ + r->next_registration = node.node_fn_registrations; \ + node.node_fn_registrations = r; \ + } \ + uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn) unformat_function_t unformat_vlib_node_variant; @@ -657,6 +656,14 @@ vlib_timing_wheel_data_get_index (u32 d) typedef struct { + clib_march_variant_type_t index; + int priority; + char *suffix; + char *desc; +} vlib_node_fn_variant_t; + +typedef struct +{ /* Public nodes. */ vlib_node_t **nodes; @@ -727,6 +734,15 @@ typedef struct /* Node index from error code */ u32 *node_by_error; + + /* Node Function Variants */ + vlib_node_fn_variant_t *variants; + + /* Node Function Default Variant Index */ + u32 node_fn_default_march_variant; + + /* Node Function march Variant by Suffix Hash */ + uword *node_fn_march_variant_by_suffix; } vlib_node_main_t; typedef u16 vlib_error_t; diff --git a/src/vlib/node_cli.c b/src/vlib/node_cli.c index c5458b218bf..1c0780517b5 100644 --- a/src/vlib/node_cli.c +++ b/src/vlib/node_cli.c @@ -618,13 +618,15 @@ show_node (vlib_main_t * vm, unformat_input_t * input, if (n->node_fn_registrations) { vlib_node_fn_registration_t *fnr = n->node_fn_registrations; + vlib_node_fn_variant_t *v; while (fnr) { + v = vec_elt_at_index (vm->node_main.variants, fnr->march_variant); if (vec_len (s) == 0) - s = format (s, "\n %-15s %=8s %6s", - "Name", "Priority", "Active"); - s = format (s, "\n %-15s %8d %=6s", fnr->name, fnr->priority, - fnr->function == n->function ? "yes" : ""); + s = format (s, "\n %-15s %=8s %6s %s", "Name", "Priority", + "Active", "Description"); + s = format (s, "\n %-15s %8d %=6s %s", v->suffix, v->priority, + fnr->function == n->function ? "yes" : "", v->desc); fnr = fnr->next_registration; } } @@ -712,11 +714,9 @@ static clib_error_t * set_node_fn(vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; - u32 node_index; + u32 node_index, march_variant; vlib_node_t *n; clib_error_t *err = 0; - vlib_node_fn_registration_t *fnr; - u8 *variant = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -727,9 +727,9 @@ set_node_fn(vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd goto done; } - if (!unformat (line_input, "%U", unformat_vlib_node_variant, &variant)) + if (!unformat (line_input, "%U", unformat_vlib_node_variant, &march_variant)) { - err = clib_error_return (0, "please specify node functional variant"); + err = clib_error_return (0, "please specify node function variant"); goto done; } @@ -737,36 +737,21 @@ set_node_fn(vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd if (n->node_fn_registrations == 0) { - err = clib_error_return (0, "node doesn't have functional variants"); + err = clib_error_return (0, "node doesn't have function variants"); goto done; } - fnr = n->node_fn_registrations; - vec_add1 (variant, 0); - - while (fnr) + if (vlib_node_set_march_variant (vm, node_index, march_variant)) { - if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1)) - { - int i; - - n->function = fnr->function; - - for (i = 0; i < vec_len (vlib_mains); i++) - { - vlib_node_runtime_t *nrt; - nrt = vlib_node_get_runtime (vlib_mains[i], n->index); - nrt->function = fnr->function; - } - goto done; - } - fnr = fnr->next_registration; + vlib_node_fn_variant_t *v; + v = vec_elt_at_index (vm->node_main.variants, march_variant); + err = clib_error_return (0, "node function variant '%s' not found", + v->suffix); + goto done; } - err = clib_error_return (0, "node functional variant '%s' not found", variant); done: - vec_free (variant); unformat_free (line_input); return err; } diff --git a/src/vlib/node_format.c b/src/vlib/node_format.c index 822a8f64e1a..54cea9ff804 100644 --- a/src/vlib/node_format.c +++ b/src/vlib/node_format.c @@ -178,6 +178,27 @@ format_vlib_cpu_time (u8 * s, va_list * va) return format (s, "%U", format_vlib_time, vm, dt); } +uword +unformat_vlib_node_variant (unformat_input_t *input, va_list *args) +{ + vlib_main_t *vm = vlib_get_main (); + u32 *march_variant = va_arg (*args, u32 *); + uword *p; + u8 *str = 0; + + if (unformat (input, "%s", &str) == 0) + return 0; + + p = hash_get (vm->node_main.node_fn_march_variant_by_suffix, str); + + vec_free (str); + + if (p) + *march_variant = p[0]; + + return p ? 1 : 0; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h index a12aea4e462..386e9168fa0 100644 --- a/src/vlib/node_funcs.h +++ b/src/vlib/node_funcs.h @@ -1189,6 +1189,9 @@ void vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...); macro. */ u32 vlib_register_node (vlib_main_t * vm, vlib_node_registration_t * r); +/* Register all node function variants */ +void vlib_register_all_node_march_variants (vlib_main_t *vm); + /* Register all static nodes registered via VLIB_REGISTER_NODE. */ void vlib_register_all_static_nodes (vlib_main_t * vm); @@ -1239,6 +1242,13 @@ vlib_node_set_dispatch_wrapper (vlib_main_t *vm, vlib_node_function_t *fn) return 0; } +int vlib_node_set_march_variant (vlib_main_t *vm, u32 node_index, + clib_march_variant_type_t march_variant); + +vlib_node_function_t * +vlib_node_get_preferred_node_fn_variant (vlib_main_t *vm, + vlib_node_fn_registration_t *regs); + #endif /* included_vlib_node_funcs_h */ /* diff --git a/src/vlib/node_init.c b/src/vlib/node_init.c index 265e88f525c..a0318a11dcd 100644 --- a/src/vlib/node_init.c +++ b/src/vlib/node_init.c @@ -41,108 +41,15 @@ #include <fcntl.h> #include <vlib/vlib.h> -typedef struct _vlib_node_march_variant -{ - struct _vlib_node_march_variant *next_variant; - char *name; -} vlib_node_march_variant_t; - -#define VLIB_VARIANT_REGISTER() \ - static vlib_node_march_variant_t \ - CLIB_MARCH_VARIANT##variant; \ - \ - static void __clib_constructor \ - CLIB_MARCH_VARIANT##_register (void) \ - { \ - extern vlib_node_march_variant_t *variants; \ - vlib_node_march_variant_t *v; \ - v = & CLIB_MARCH_VARIANT##variant; \ - v->name = CLIB_MARCH_VARIANT_STR; \ - v->next_variant = variants; \ - variants = v; \ - } \ - -VLIB_VARIANT_REGISTER (); - -#ifndef CLIB_MARCH_VARIANT - -vlib_node_march_variant_t *variants = 0; - -uword -unformat_vlib_node_variant (unformat_input_t * input, va_list * args) -{ - u8 **variant = va_arg (*args, u8 **); - vlib_node_march_variant_t *v = variants; - - if (!unformat (input, "%v", variant)) - return 0; - - while (v) - { - if (!strncmp (v->name, (char *) *variant, vec_len (*variant))) - return 1; - - v = v->next_variant; - } - - return 0; -} - -static_always_inline void -vlib_update_nr_variant_default (vlib_node_registration_t *nr, u8 *variant) -{ - vlib_node_fn_registration_t *fnr = nr->node_fn_registrations; - vlib_node_fn_registration_t *p_reg = 0; - vlib_node_fn_registration_t *v_reg = 0; - u32 tmp; - - while (fnr) - { - /* which is the highest priority registration */ - if (!p_reg || fnr->priority > p_reg->priority) - p_reg = fnr; - - /* which is the variant we want to prioritize */ - if (!strncmp (fnr->name, (char *) variant, vec_len (variant) - 1)) - v_reg = fnr; - - fnr = fnr->next_registration; - } - - /* node doesn't have the variants */ - if (!v_reg) - return; - - ASSERT (p_reg != 0 && v_reg != 0); - - /* swap priorities */ - tmp = p_reg->priority; - p_reg->priority = v_reg->priority; - v_reg->priority = tmp; - -} - static clib_error_t * -vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input) +vlib_node_config (vlib_main_t *vm, unformat_input_t *input) { clib_error_t *error = 0; - vlib_node_registration_t *nr, **all; unformat_input_t sub_input; - uword *hash = 0, *p; - u8 *variant = 0; - u8 *s = 0; - - all = 0; - hash = hash_create_string (0, sizeof (uword)); - - nr = vm->node_main.node_registrations; - while (nr) - { - hash_set_mem (hash, nr->name, vec_len (all)); - vec_add1 (all, nr); - - nr = nr->next_registration; - } + u32 *march_variant_by_node = 0; + clib_march_variant_type_t march_variant; + u32 node_index; + int i; /* specify prioritization defaults for all graph nodes */ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) @@ -153,48 +60,34 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input) while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT) { if (!unformat (&sub_input, "variant %U", - unformat_vlib_node_variant, &variant)) + unformat_vlib_node_variant, &march_variant)) return clib_error_return (0, "please specify a valid node variant"); - vec_add1 (variant, 0); - - nr = vm->node_main.node_registrations; - while (nr) - { - vlib_update_nr_variant_default (nr, variant); - nr = nr->next_registration; - } - vec_free (variant); + vec_validate_init_empty (march_variant_by_node, + vec_len (vm->node_main.nodes) - 1, ~0); + vec_foreach_index (i, march_variant_by_node) + march_variant_by_node[i] = march_variant; + vm->node_main.node_fn_default_march_variant = march_variant; + unformat_free (&sub_input); } } else /* specify prioritization for an individual graph node */ - if (unformat (input, "%s", &s)) + if (unformat (input, "%U", unformat_vlib_node, vm, &node_index)) { - if (!(p = hash_get_mem (hash, s))) - { - error = clib_error_return (0, - "node variants: unknown graph node '%s'", - s); - break; - } - - nr = vec_elt (all, p[0]); - if (unformat (input, "%U", unformat_vlib_cli_sub_input, &sub_input)) { while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT) { if (!unformat (&sub_input, "variant %U", - unformat_vlib_node_variant, &variant)) + unformat_vlib_node_variant, &march_variant)) return clib_error_return (0, "please specify a valid node variant"); - vec_add1 (variant, 0); - - vlib_update_nr_variant_default (nr, variant); - - vec_free (variant); + vec_validate_init_empty (march_variant_by_node, node_index, + ~0); + march_variant_by_node[node_index] = march_variant; + unformat_free (&sub_input); } } } @@ -204,16 +97,19 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input) } } - hash_free (hash); - vec_free (all); + if (march_variant_by_node) + { + vec_foreach_index (i, march_variant_by_node) + if (march_variant_by_node[i] != ~0) + vlib_node_set_march_variant (vm, i, march_variant_by_node[i]); + vec_free (march_variant_by_node); + } unformat_free (input); return error; } -VLIB_EARLY_CONFIG_FUNCTION (vlib_early_node_config, "node"); - -#endif +VLIB_CONFIG_FUNCTION (vlib_node_config, "node"); /* * fd.io coding-style-patch-verification: ON |