From 0cea6395a9cc768c644c46962fd83dacdcef71f5 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Wed, 23 Jul 2025 12:42:33 +0000 Subject: [PATCH] dev: add option to assign one rx and one tx queue per thread queue 0 -> main queue 1 -> thread 1 (worker 0) queue 2 -> thread 2 (worker 1) etc... example startup.conf entry: devices { dev pci/0002:04:00.0 { port 0 { name eth2 flags queue-per-thread } } } Type: improvement Change-Id: Ia1c216905c5e4368a0e2e47688fd87348be20106 Signed-off-by: Damjan Marion --- src/vnet/dev/api.c | 10 ++++++++++ src/vnet/dev/dev.h | 8 ++++++-- src/vnet/dev/dev_api.c | 4 ++++ src/vnet/dev/port.c | 22 +++++++++++++++++++--- src/vnet/dev/queue.c | 19 ++++++------------- src/vnet/dev/types.h | 3 ++- 6 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/vnet/dev/api.c b/src/vnet/dev/api.c index b27e84b1152..55c3de3b4ca 100644 --- a/src/vnet/dev/api.c +++ b/src/vnet/dev/api.c @@ -199,6 +199,15 @@ vnet_dev_api_create_port_if (vlib_main_t *vm, return VNET_DEV_ERR_NOT_SUPPORTED; } + if (args->flags.e & VNET_DEV_PORT_F_QUEUE_PER_THREAD) + { + if (args->num_rx_queues) + return VNET_DEV_ERR_INVALID_NUM_RX_QUEUES; + if (args->num_tx_queues) + return VNET_DEV_ERR_INVALID_NUM_TX_QUEUES; + args->num_rx_queues = args->num_tx_queues = n_threads; + } + if (args->num_rx_queues) { if (args->num_rx_queues > port->attr.max_rx_queues) @@ -240,6 +249,7 @@ vnet_dev_api_create_port_if (vlib_main_t *vm, clib_memcpy (a.name, args->intf_name, sizeof (a.name)); a.default_is_intr_mode = default_is_intr_mode; a.consistent_qp = (args->flags.n & VNET_DEV_PORT_F_CONSISTENT_QP) != 0; + a.queue_per_thread = (args->flags.n & VNET_DEV_PORT_F_QUEUE_PER_THREAD) != 0; rv = vnet_dev_process_call_port_op_with_ptr (vm, port, vnet_dev_port_if_create, &a); diff --git a/src/vnet/dev/dev.h b/src/vnet/dev/dev.h index 7e0a3f25df7..2a72cb2898d 100644 --- a/src/vnet/dev/dev.h +++ b/src/vnet/dev/dev.h @@ -621,6 +621,7 @@ typedef struct u16 txq_sz; u8 default_is_intr_mode : 1; u8 consistent_qp : 1; + u8 queue_per_thread : 1; /* return */ u32 sw_if_index; @@ -665,8 +666,11 @@ vnet_dev_port_op_with_ptr_t vnet_dev_port_if_create; vnet_dev_port_op_t vnet_dev_port_if_remove; /* queue.c */ -vnet_dev_rv_t vnet_dev_rx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16); -vnet_dev_rv_t vnet_dev_tx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16); +vnet_dev_rv_t vnet_dev_rx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16, + vnet_dev_queue_id_t, + clib_thread_index_t); +vnet_dev_rv_t vnet_dev_tx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16, + vnet_dev_queue_id_t); vnet_dev_rx_queue_op_no_rv_t vnet_dev_rx_queue_free; vnet_dev_tx_queue_op_no_rv_t vnet_dev_tx_queue_free; void vnet_dev_rx_queue_add_counters (vlib_main_t *, vnet_dev_rx_queue_t *, diff --git a/src/vnet/dev/dev_api.c b/src/vnet/dev/dev_api.c index 5e9ac502b5d..2804817621a 100644 --- a/src/vnet/dev/dev_api.c +++ b/src/vnet/dev/dev_api.c @@ -23,6 +23,10 @@ static u16 vnet_dev_api_msg_id_base; foreach_vnet_dev_flag; #undef _ +#ifndef VL_API_DEV_PORT_FLAG_QUEUE_PER_THREAD +#define VL_API_DEV_PORT_FLAG_QUEUE_PER_THREAD VNET_DEV_PORT_F_QUEUE_PER_THREAD +#endif + #define _(b, n, d) \ STATIC_ASSERT ((int) VL_API_DEV_PORT_FLAG_##n == (int) VNET_DEV_PORT_F_##n, \ ""); diff --git a/src/vnet/dev/port.c b/src/vnet/dev/port.c index e538b89a630..c03a56086af 100644 --- a/src/vnet/dev/port.c +++ b/src/vnet/dev/port.c @@ -608,11 +608,27 @@ vnet_dev_port_if_create (vlib_main_t *vm, vnet_dev_port_t *port, void *ptr) a->num_rx_queues, a->rxq_sz, a->num_tx_queues, a->txq_sz); for (int i = 0; i < ifs->num_rx_queues; i++) - if ((rv = vnet_dev_rx_queue_alloc (vm, port, ifs->rxq_sz)) != VNET_DEV_OK) - goto error; + { + clib_thread_index_t ti = 0; + if (n_threads > 1) + { + if (!a->queue_per_thread) + { + ti = dm->next_rx_queue_thread++; + if (dm->next_rx_queue_thread >= n_threads) + dm->next_rx_queue_thread = 0; + } + else + ti = i; + } + if ((rv = vnet_dev_rx_queue_alloc (vm, port, ifs->rxq_sz, i, ti)) != + VNET_DEV_OK) + goto error; + } for (u32 i = 0; i < ifs->num_tx_queues; i++) - if ((rv = vnet_dev_tx_queue_alloc (vm, port, ifs->txq_sz)) != VNET_DEV_OK) + if ((rv = vnet_dev_tx_queue_alloc (vm, port, ifs->txq_sz, i)) != + VNET_DEV_OK) goto error; for (ti = 0; ti < n_threads; ti++) diff --git a/src/vnet/dev/queue.c b/src/vnet/dev/queue.c index 57ed3dcae3b..c70bf8f6117 100644 --- a/src/vnet/dev/queue.c +++ b/src/vnet/dev/queue.c @@ -29,13 +29,12 @@ vnet_dev_rx_queue_free (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq) vnet_dev_rv_t vnet_dev_rx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port, - u16 queue_size) + u16 queue_size, vnet_dev_queue_id_t qid, + clib_thread_index_t ti) { - vnet_dev_main_t *dm = &vnet_dev_main; vnet_dev_rx_queue_t *rxq, **qp; vnet_dev_t *dev = port->dev; vnet_dev_rv_t rv = VNET_DEV_OK; - u16 n_threads = vlib_get_n_threads (); vnet_dev_port_validate (vm, port); @@ -54,15 +53,10 @@ vnet_dev_rx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port, rxq->index = qp - port->rx_queues; /* default queue id - can be changed by driver */ - rxq->queue_id = qp - port->rx_queues; + rxq->queue_id = qid; ASSERT (rxq->queue_id < port->attr.max_rx_queues); - if (n_threads > 1) - { - rxq->rx_thread_index = dm->next_rx_queue_thread++; - if (dm->next_rx_queue_thread >= n_threads) - dm->next_rx_queue_thread = 1; - } + rxq->rx_thread_index = ti; if (port->rx_queue_ops.alloc) rv = port->rx_queue_ops.alloc (vm, rxq); @@ -122,7 +116,7 @@ vnet_dev_tx_queue_free (vlib_main_t *vm, vnet_dev_tx_queue_t *txq) vnet_dev_rv_t vnet_dev_tx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port, - u16 queue_size) + u16 queue_size, vnet_dev_queue_id_t qid) { vnet_dev_tx_queue_t *txq, **qp; vnet_dev_t *dev = port->dev; @@ -142,8 +136,7 @@ vnet_dev_tx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port, txq->size = queue_size; txq->index = qp - port->tx_queues; - /* default queue id - can be changed by driver */ - txq->queue_id = qp - port->tx_queues; + txq->queue_id = qid; ASSERT (txq->queue_id < port->attr.max_tx_queues); if (port->tx_queue_ops.alloc) diff --git a/src/vnet/dev/types.h b/src/vnet/dev/types.h index 24799ac8138..0562b3a49e8 100644 --- a/src/vnet/dev/types.h +++ b/src/vnet/dev/types.h @@ -51,7 +51,8 @@ typedef union /* do not change bit assignments - API dependency */ #define foreach_vnet_dev_port_flag \ _ (0, INTERRUPT_MODE, "enable interrupt mode") \ - _ (1, CONSISTENT_QP, "consistent queue pairs") + _ (1, CONSISTENT_QP, "consistent queue pairs") \ + _ (2, QUEUE_PER_THREAD, "one rx and one tx queue per thread (inc main)") typedef union { -- 2.16.6