vlib: refactor node function variants 16/31616/7
authorDamjan Marion <damarion@cisco.com>
Wed, 10 Mar 2021 13:35:28 +0000 (14:35 +0100)
committerDave Wallace <dwallacelf@gmail.com>
Thu, 11 Mar 2021 17:30:34 +0000 (17:30 +0000)
It allows default variant selection from startup.conf

Type: improvement
Change-Id: Idff95e12dd0c105dab7c905089548b05a6e974e0
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vlib/main.c
src/vlib/node.c
src/vlib/node.h
src/vlib/node_cli.c
src/vlib/node_format.c
src/vlib/node_funcs.h
src/vlib/node_init.c
src/vnet/interface.c
src/vnet/interface.h
src/vppinfra/cpu.h

index 111941c..02fdc89 100644 (file)
@@ -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);
 
index 25e249b..618baec 100644 (file)
@@ -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. */
@@ -506,6 +534,40 @@ null_node_fn (vlib_main_t * vm,
   return n_vectors;
 }
 
+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)
 {
@@ -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
  *
index 0c815ea..9a3bb83 100644 (file)
@@ -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;
 
@@ -655,6 +654,14 @@ vlib_timing_wheel_data_get_index (u32 d)
   return d / 2;
 }
 
+typedef struct
+{
+  clib_march_variant_type_t index;
+  int priority;
+  char *suffix;
+  char *desc;
+} vlib_node_fn_variant_t;
+
 typedef struct
 {
   /* Public 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;
index c5458b2..1c07805 100644 (file)
@@ -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;
 }
index 822a8f6..54cea9f 100644 (file)
@@ -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
  *
index a12aea4..386e916 100644 (file)
@@ -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 */
 
 /*
index 265e88f..a0318a1 100644 (file)
 #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
index 638dc49..13deacc 100644 (file)
@@ -774,7 +774,6 @@ setup_tx_node (vlib_main_t * vm,
 {
   vlib_node_t *n = vlib_get_node (vm, node_index);
 
-  n->function = dev_class->tx_function;
   n->format_trace = dev_class->format_tx_trace;
 
   /// XXX: Update this to use counter structure
@@ -855,7 +854,7 @@ vnet_register_interface (vnet_main_t * vnm,
   hw->min_packet_bytes = 0;
   vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, 0);
 
-  if (dev_class->tx_function == 0)
+  if (dev_class->tx_function == 0 && dev_class->tx_fn_registrations == 0)
     goto no_output_nodes;      /* No output/tx nodes to create */
 
   tx_node_name = (char *) format (0, "%v-tx", hw->name);
@@ -911,7 +910,14 @@ vnet_register_interface (vnet_main_t * vnm,
       /* *INDENT-ON* */
 
       node = vlib_get_node (vm, hw->tx_node_index);
-      node->function = dev_class->tx_function;
+      if (dev_class->tx_fn_registrations)
+       {
+         node->node_fn_registrations = dev_class->tx_fn_registrations;
+         node->function = vlib_node_get_preferred_node_fn_variant (
+           vm, dev_class->tx_fn_registrations);
+       }
+      else
+       node->function = dev_class->tx_function;
       node->format_trace = dev_class->format_tx_trace;
       /* *INDENT-OFF* */
       foreach_vlib_main ({
@@ -1369,25 +1375,13 @@ vnet_interface_init (vlib_main_t * vm)
        c->index = vec_len (im->device_classes);
        hash_set_mem (im->device_class_by_name, c->name, c->index);
 
+       /* to avoid confusion, please remove ".tx_function" statement
+         from VNET_DEVICE_CLASS() if using function candidates */
+       ASSERT (c->tx_fn_registrations == 0 || c->tx_function == 0);
+
        if (c->tx_fn_registrations)
-         {
-           vlib_node_fn_registration_t *fnr = c->tx_fn_registrations;
-           int priority = -1;
-
-           /* to avoid confusion, please remove ".tx_function" statement
-              from VNET_DEVICE_CLASS() if using function candidates */
-           ASSERT (c->tx_function == 0);
-
-           while (fnr)
-             {
-               if (fnr->priority > priority)
-                 {
-                   priority = fnr->priority;
-                   c->tx_function = fnr->function;
-                 }
-               fnr = fnr->next_registration;
-             }
-         }
+         c->tx_function = vlib_node_get_preferred_node_fn_variant (
+           vm, c->tx_fn_registrations);
 
        vec_add1 (im->device_classes, c[0]);
        c = c->next_class_registration;
index 83abea4..9c58442 100644 (file)
@@ -326,8 +326,7 @@ static __clib_unused vnet_device_class_t __clib_unused_##x
     extern vnet_device_class_t devclass;                                      \
     vlib_node_fn_registration_t *r;                                           \
     r = &CLIB_MARCH_SFX (devclass##_tx_fn_registration);                      \
-    r->priority = CLIB_MARCH_FN_PRIORITY ();                                  \
-    r->name = CLIB_MARCH_VARIANT_STR;                                         \
+    r->march_variant = CLIB_MARCH_SFX (CLIB_MARCH_VARIANT_TYPE);              \
     r->next_registration = devclass.tx_fn_registrations;                      \
     devclass.tx_fn_registrations = r;                                         \
   }                                                                           \
index 6a81218..bc4ee58 100644 (file)
 #include <sys/syscall.h>
 #include <vppinfra/format.h>
 
-/*
- * multiarchitecture support. Adding new entry will produce
- * new graph node function variant optimized for specific cpu
- * microarchitecture.
- * Order is important for runtime selection, as 1st match wins...
- */
-
-#if __x86_64__ && CLIB_DEBUG == 0
-#define foreach_march_variant(macro, x) \
-  macro(avx2,  x, "arch=core-avx2")
+#if defined(__x86_64__)
+#define foreach_march_variant                                                 \
+  _ (hsw, "Intel Haswell")                                                    \
+  _ (trm, "Intel Tremont")                                                    \
+  _ (skx, "Intel Skylake (server) / Cascade Lake")                            \
+  _ (icl, "Intel Ice Lake")
+#elif defined(__aarch64__)
+#define foreach_march_variant                                                 \
+  _ (octeontx2, "Marvell Octeon TX2")                                         \
+  _ (thunderx2t99, "Marvell ThunderX2 T99")                                   \
+  _ (qdf24xx, "Qualcomm CentriqTM 2400")                                      \
+  _ (cortexa72, "ARM Cortex-A72")                                             \
+  _ (neoversen1, "ARM Neoverse N1")
 #else
-#define foreach_march_variant(macro, x)
+#define foreach_march_variant
 #endif
 
+typedef enum
+{
+  CLIB_MARCH_VARIANT_TYPE = 0,
+#define _(s, n) CLIB_MARCH_VARIANT_TYPE_##s,
+  foreach_march_variant
+#undef _
+    CLIB_MARCH_TYPE_N_VARIANTS
+} clib_march_variant_type_t;
 
 #if __GNUC__ > 4  && !__clang__ && CLIB_DEBUG == 0
 #define CLIB_CPU_OPTIMIZED __attribute__ ((optimize ("O3")))
 #define CLIB_CPU_OPTIMIZED
 #endif
 
-
-#define CLIB_MULTIARCH_ARCH_CHECK(arch, fn, tgt)                       \
-  if (clib_cpu_supports_ ## arch())                                    \
-    return & fn ## _ ##arch;
-
-/* FIXME to be removed */
-#define CLIB_MULTIARCH_SELECT_FN(fn,...)
-
 #ifdef CLIB_MARCH_VARIANT
 #define __CLIB_MULTIARCH_FN(a,b) a##_##b
 #define _CLIB_MULTIARCH_FN(a,b) __CLIB_MULTIARCH_FN(a,b)