From 82569141943b1d04037282082cc47eb2b1c0556a Mon Sep 17 00:00:00 2001 From: Mohammed Hawari Date: Wed, 6 Nov 2024 17:13:02 +0100 Subject: dev: introduce consistent_qp feature For some devices, queues are organized as pairs (rx/tx). In this case, it is desirable that a worker receives packet and send packets for the same pair. This patch enables this by assigning txq to workers first and ending with main. Change-Id: I3de4afbf74a265d5275c6a5d9a905b51dd661b22 Type: feature Signed-off-by: Mohammed Hawari --- src/vnet/dev/api.c | 2 ++ src/vnet/dev/dev.api | 1 + src/vnet/dev/dev.h | 1 + src/vnet/dev/format.c | 4 ++-- src/vnet/dev/port.c | 8 ++++++-- src/vnet/dev/types.h | 3 ++- 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/vnet/dev/api.c b/src/vnet/dev/api.c index 0f4bd0b653e..48ceccf3b6c 100644 --- a/src/vnet/dev/api.c +++ b/src/vnet/dev/api.c @@ -238,6 +238,8 @@ vnet_dev_api_create_port_if (vlib_main_t *vm, clib_memcpy (port->intf.name, args->intf_name, sizeof (port->intf.name)); port->intf.default_is_intr_mode = default_is_intr_mode; + port->intf.consistent_qp = + (args->flags.n & VNET_DEV_PORT_F_CONSISTENT_QP) != 0; rv = vnet_dev_process_call_port_op (vm, port, vnet_dev_port_if_create); args->sw_if_index = (rv == VNET_DEV_OK) ? port->intf.sw_if_index : ~0; diff --git a/src/vnet/dev/dev.api b/src/vnet/dev/dev.api index 552b778949b..423d0ee8505 100644 --- a/src/vnet/dev/dev.api +++ b/src/vnet/dev/dev.api @@ -12,6 +12,7 @@ enumflag dev_flags : u32 enumflag dev_port_flags : u32 { VL_API_DEV_PORT_FLAG_INTERRUPT_MODE = 0x1, + VL_API_DEV_PORT_FLAG_CONSISTENT_QP = 0x2, }; autoendian define dev_attach diff --git a/src/vnet/dev/dev.h b/src/vnet/dev/dev.h index 57c6d09d181..76ff4f55b71 100644 --- a/src/vnet/dev/dev.h +++ b/src/vnet/dev/dev.h @@ -356,6 +356,7 @@ typedef struct vnet_dev_port u8 feature_arc : 1; u8 redirect_to_node : 1; u8 default_is_intr_mode : 1; + u8 consistent_qp : 1; u32 tx_node_index; u32 hw_if_index; u32 sw_if_index; diff --git a/src/vnet/dev/format.c b/src/vnet/dev/format.c index bde245cafee..fb46fcc47bc 100644 --- a/src/vnet/dev/format.c +++ b/src/vnet/dev/format.c @@ -319,7 +319,7 @@ unformat_vnet_dev_port_flags (unformat_input_t *input, va_list *args) #undef _ }; u64 flag_values[] = { -#define _(b, n, d) 1ull << (b) +#define _(b, n, d) 1ull << (b), foreach_vnet_dev_port_flag #undef _ }; @@ -395,7 +395,7 @@ format_vnet_dev_port_flags (u8 *s, va_list *args) #undef _ }; u64 flag_values[] = { -#define _(b, n, d) 1ull << (b) +#define _(b, n, d) 1ull << (b), foreach_vnet_dev_port_flag #undef _ }; diff --git a/src/vnet/dev/port.c b/src/vnet/dev/port.c index 7126ceed731..5bd4edf05c1 100644 --- a/src/vnet/dev/port.c +++ b/src/vnet/dev/port.c @@ -520,6 +520,7 @@ vnet_dev_port_if_create (vlib_main_t *vm, vnet_dev_port_t *port) vnet_dev_instance_t *di; vnet_dev_rv_t rv; u16 ti = 0; + u8 is_consistent_qp = port->intf.consistent_qp; if (port->intf.name[0] == 0) { @@ -556,9 +557,12 @@ vnet_dev_port_if_create (vlib_main_t *vm, vnet_dev_port_t *port) foreach_vnet_dev_port_tx_queue (q, port) { - q->assigned_threads = clib_bitmap_set (q->assigned_threads, ti, 1); + /* if consistent_qp is enabled, we start by assigning queues to workers + * and we end with main */ + u16 real_ti = (ti + is_consistent_qp) % n_threads; + q->assigned_threads = clib_bitmap_set (q->assigned_threads, real_ti, 1); log_debug (dev, "port %u tx queue %u assigned to thread %u", - port->port_id, q->queue_id, ti); + port->port_id, q->queue_id, real_ti); if (++ti >= n_threads) break; } diff --git a/src/vnet/dev/types.h b/src/vnet/dev/types.h index 006d18e5bc5..24799ac8138 100644 --- a/src/vnet/dev/types.h +++ b/src/vnet/dev/types.h @@ -50,7 +50,8 @@ typedef union /* do not change bit assignments - API dependency */ #define foreach_vnet_dev_port_flag \ - _ (0, INTERRUPT_MODE, "enable interrupt mode") + _ (0, INTERRUPT_MODE, "enable interrupt mode") \ + _ (1, CONSISTENT_QP, "consistent queue pairs") typedef union { -- cgit 1.2.3-korg