aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2018-07-23 14:45:57 +0200
committerDamjan Marion <dmarion@me.com>2018-08-11 15:01:42 +0000
commitdd8e7d0e512425ec05de652a3c71028561e0f40a (patch)
tree849eaaabe4c2a07a0bd9cf8173e6cfbac31ffdf5 /src/vnet
parent7f1f7e7865f07f98b5ab6d4ab483cd9a51e4ce4e (diff)
Multiversioning: Device (tx) function constructor
Change-Id: I39f87ca161c891fb22462a23188982fef7c3243f Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/devices/virtio/vhost_user_output.c21
-rw-r--r--src/vnet/interface.c21
-rw-r--r--src/vnet/interface.h21
3 files changed, 45 insertions, 18 deletions
diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c
index b41583708b3..9c65f249b4b 100644
--- a/src/vnet/devices/virtio/vhost_user_output.c
+++ b/src/vnet/devices/virtio/vhost_user_output.c
@@ -223,11 +223,9 @@ vhost_user_tx_copy (vhost_user_intf_t * vui, vhost_copy_t * cpy,
return 0;
}
-
-uword
-CLIB_MULTIARCH_FN (vhost_user_tx) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VNET_DEVICE_CLASS_TX_FN (vhost_user_device_class) (vlib_main_t * vm,
+ vlib_node_runtime_t *
+ node, vlib_frame_t * frame)
{
u32 *buffers = vlib_frame_args (frame);
u32 n_left = frame->n_vectors;
@@ -636,7 +634,6 @@ vhost_user_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
/* *INDENT-OFF* */
VNET_DEVICE_CLASS (vhost_user_device_class) = {
.name = "vhost-user",
- .tx_function = vhost_user_tx,
.tx_function_n_errors = VHOST_USER_TX_FUNC_N_ERROR,
.tx_function_error_strings = vhost_user_tx_func_error_strings,
.format_device_name = format_vhost_user_interface_name,
@@ -646,18 +643,6 @@ VNET_DEVICE_CLASS (vhost_user_device_class) = {
.format_tx_trace = format_vhost_trace,
};
-#if __x86_64__
-vlib_node_function_t __clib_weak vhost_user_tx_avx512;
-vlib_node_function_t __clib_weak vhost_user_tx_avx2;
-static void __clib_constructor
-vhost_user_tx_multiarch_select (void)
-{
- if (vhost_user_tx_avx512 && clib_cpu_supports_avx512f ())
- vhost_user_device_class.tx_function = vhost_user_tx_avx512;
- else if (vhost_user_tx_avx2 && clib_cpu_supports_avx2 ())
- vhost_user_device_class.tx_function = vhost_user_tx_avx2;
-}
-#endif
#endif
/* *INDENT-ON* */
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index ca4dc493aac..1e69ccbf6ea 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -1359,6 +1359,27 @@ 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);
+
+ 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" statiement
+ 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;
+ }
+ }
+
vec_add1 (im->device_classes, c[0]);
c = c->next_class_registration;
}
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index d869b0c70a2..e9adfe84cbf 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -195,6 +195,9 @@ typedef struct _vnet_device_class
/* Transmit function. */
vlib_node_function_t *tx_function;
+ /* Transmit function candidate registration with priority */
+ vlib_node_fn_registration_t *tx_fn_registrations;
+
/* Error strings indexed by error code for this node. */
char **tx_function_error_strings;
@@ -265,6 +268,24 @@ static void __vnet_rm_device_class_registration_##x (void) \
} \
__VA_ARGS__ vnet_device_class_t x
+#define VNET_DEVICE_CLASS_TX_FN(devclass) \
+uword CLIB_MARCH_SFX (devclass##_tx_fn)(); \
+static vlib_node_fn_registration_t \
+ CLIB_MARCH_SFX(devclass##_tx_fn_registration) = \
+ { .function = &CLIB_MARCH_SFX (devclass##_tx_fn), }; \
+ \
+static void __clib_constructor \
+CLIB_MARCH_SFX (devclass##_tx_fn_multiarch_register) (void) \
+{ \
+ 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->next_registration = devclass.tx_fn_registrations; \
+ devclass.tx_fn_registrations = r; \
+} \
+uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (devclass##_tx_fn)
+
#define VLIB_DEVICE_TX_FUNCTION_CLONE_TEMPLATE(arch, fn, tgt) \
uword \
__attribute__ ((flatten)) \