summaryrefslogtreecommitdiffstats
path: root/src/vlib/node_init.c
diff options
context:
space:
mode:
authorRay Kinsella <mdr@ashroe.eu>2020-03-10 14:35:32 +0000
committerDamjan Marion <dmarion@me.com>2020-04-28 11:10:50 +0000
commit4830e4f78fb8e46b23a1a0711cd06969a77d8d95 (patch)
tree36ff9c5252a62a8b5a50867a31c094c6a1bc1cda /src/vlib/node_init.c
parenta568a19b2956ed8b94b11c2ef041412473dc8442 (diff)
vlib: startup multi-arch variant configuration
Support for startup node multi-arch variant selection through startup.conf. This is to facilitate unit, functional testing and benchmarking of non-default multi-arch variant node code path. Also added parameters to make test, to specific using multi-arch variants in unit testing. Type: improvement Signed-off-by: Ray Kinsella <mdr@ashroe.eu> Change-Id: I94fd332bb629683b7a7dd770ee9f615a9a424060
Diffstat (limited to 'src/vlib/node_init.c')
-rw-r--r--src/vlib/node_init.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/vlib/node_init.c b/src/vlib/node_init.c
new file mode 100644
index 00000000000..47d288c6ef0
--- /dev/null
+++ b/src/vlib/node_init.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2020 Intel and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * node_init.c: node march variant startup initialization
+ *
+ * Copyright (c) 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <sys/types.h>
+#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)
+{
+ 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;
+ }
+
+ /* specify prioritization defaults for all graph nodes */
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "default %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))
+ 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);
+ }
+ }
+ else /* specify prioritization for an individual graph node */
+ if (unformat (input, "%s", &s))
+ {
+ 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))
+ 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);
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ hash_free (hash);
+ vec_free (all);
+ unformat_free (input);
+
+ return error;
+}
+
+VLIB_EARLY_CONFIG_FUNCTION (vlib_early_node_config, "node");
+
+#endif
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */