diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/avf/avf.h | 2 | ||||
-rw-r--r-- | src/plugins/avf/device.c | 1 | ||||
-rw-r--r-- | src/plugins/avf/output.c | 22 | ||||
-rw-r--r-- | src/plugins/dpdk/device/device.c | 20 | ||||
-rw-r--r-- | src/plugins/memif/device.c | 20 | ||||
-rw-r--r-- | src/vnet/devices/virtio/vhost_user_output.c | 21 | ||||
-rw-r--r-- | src/vnet/interface.c | 21 | ||||
-rw-r--r-- | src/vnet/interface.h | 21 |
8 files changed, 54 insertions, 74 deletions
diff --git a/src/plugins/avf/avf.h b/src/plugins/avf/avf.h index 3ee80158667..1dc5d96ec72 100644 --- a/src/plugins/avf/avf.h +++ b/src/plugins/avf/avf.h @@ -216,8 +216,6 @@ void avf_delete_if (vlib_main_t * vm, avf_device_t * ad); extern vlib_node_registration_t avf_input_node; extern vnet_device_class_t avf_device_class; -uword avf_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame); /* format.c */ format_function_t format_avf_device; diff --git a/src/plugins/avf/device.c b/src/plugins/avf/device.c index a6af902a7fc..94b5ca46648 100644 --- a/src/plugins/avf/device.c +++ b/src/plugins/avf/device.c @@ -1299,7 +1299,6 @@ avf_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, VNET_DEVICE_CLASS (avf_device_class,) = { .name = "Adaptive Virtual Function (AVF) interface", - .tx_function = avf_interface_tx, .format_device = format_avf_device, .format_device_name = format_avf_device_name, .admin_up_down_function = avf_interface_admin_up_down, diff --git a/src/plugins/avf/output.c b/src/plugins/avf/output.c index 68420a7a1d4..2001c117d38 100644 --- a/src/plugins/avf/output.c +++ b/src/plugins/avf/output.c @@ -34,10 +34,9 @@ avf_tx_desc_get_dtyp (avf_tx_desc_t * d) return d->qword[1] & 0x0f; } -uword -CLIB_MULTIARCH_FN (avf_interface_tx) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +VNET_DEVICE_CLASS_TX_FN (avf_device_class) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { avf_main_t *am = &avf_main; vnet_interface_output_runtime_t *rd = (void *) node->runtime_data; @@ -159,21 +158,6 @@ CLIB_MULTIARCH_FN (avf_interface_tx) (vlib_main_t * vm, return frame->n_vectors - n_left; } -#ifndef CLIB_MARCH_VARIANT -#if __x86_64__ -vlib_node_function_t __clib_weak avf_interface_tx_avx512; -vlib_node_function_t __clib_weak avf_interface_tx_avx2; -static void __clib_constructor -avf_interface_tx_multiarch_select (void) -{ - if (avf_interface_tx_avx512 && clib_cpu_supports_avx512f ()) - avf_device_class.tx_function = avf_interface_tx_avx512; - else if (avf_interface_tx_avx2 && clib_cpu_supports_avx2 ()) - avf_device_class.tx_function = avf_interface_tx_avx2; -} -#endif -#endif - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index d5ab2585c93..8776e09ed05 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -327,10 +327,9 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, * node. It first copies packets on the frame to a per-thread arrays * containing the rte_mbuf pointers. */ -uword -CLIB_MULTIARCH_FN (dpdk_interface_tx) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * f) +VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * f) { dpdk_main_t *dm = &dpdk_main; vnet_interface_output_runtime_t *rd = (void *) node->runtime_data; @@ -663,7 +662,6 @@ done: /* *INDENT-OFF* */ VNET_DEVICE_CLASS (dpdk_device_class) = { .name = "dpdk", - .tx_function = dpdk_interface_tx, .tx_function_n_errors = DPDK_TX_FUNC_N_ERROR, .tx_function_error_strings = dpdk_tx_func_error_strings, .format_device_name = format_dpdk_device_name, @@ -679,18 +677,6 @@ VNET_DEVICE_CLASS (dpdk_device_class) = { }; /* *INDENT-ON* */ -#if __x86_64__ -vlib_node_function_t __clib_weak dpdk_interface_tx_avx512; -vlib_node_function_t __clib_weak dpdk_interface_tx_avx2; -static void __clib_constructor -dpdk_interface_tx_multiarch_select (void) -{ - if (dpdk_interface_tx_avx512 && clib_cpu_supports_avx512f ()) - dpdk_device_class.tx_function = dpdk_interface_tx_avx512; - else if (dpdk_interface_tx_avx2 && clib_cpu_supports_avx2 ()) - dpdk_device_class.tx_function = dpdk_interface_tx_avx2; -} -#endif #endif #define UP_DOWN_FLAG_EVENT 1 diff --git a/src/plugins/memif/device.c b/src/plugins/memif/device.c index 5c8eb3f082c..f86d692a103 100644 --- a/src/plugins/memif/device.c +++ b/src/plugins/memif/device.c @@ -400,10 +400,9 @@ no_free_slots: return frame->n_vectors; } -uword -CLIB_MULTIARCH_FN (memif_interface_tx) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +VNET_DEVICE_CLASS_TX_FN (memif_device_class) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { memif_main_t *nm = &memif_main; vnet_interface_output_runtime_t *rund = (void *) node->runtime_data; @@ -504,7 +503,6 @@ memif_subif_add_del_function (vnet_main_t * vnm, /* *INDENT-OFF* */ VNET_DEVICE_CLASS (memif_device_class) = { .name = "memif", - .tx_function = memif_interface_tx, .format_device_name = format_memif_device_name, .format_device = format_memif_device, .format_tx_trace = format_memif_tx_trace, @@ -517,18 +515,6 @@ VNET_DEVICE_CLASS (memif_device_class) = { .rx_mode_change_function = memif_interface_rx_mode_change, }; -#if __x86_64__ -vlib_node_function_t __clib_weak memif_interface_tx_avx512; -vlib_node_function_t __clib_weak memif_interface_tx_avx2; -static void __clib_constructor -memif_interface_tx_multiarch_select (void) -{ - if (memif_interface_tx_avx512 && clib_cpu_supports_avx512f ()) - memif_device_class.tx_function = memif_interface_tx_avx512; - else if (memif_interface_tx_avx2 && clib_cpu_supports_avx2 ()) - memif_device_class.tx_function = memif_interface_tx_avx2; -} -#endif #endif /* *INDENT-ON* */ 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)) \ |