Multiversioning: Device (tx) function constructor
Change-Id: I39f87ca161c891fb22462a23188982fef7c3243f Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
This commit is contained in:
committed by
Damjan Marion
parent
7f1f7e7865
commit
dd8e7d0e51
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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* */
|
||||
|
||||
@@ -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* */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)) \
|
||||
|
||||
Reference in New Issue
Block a user