diff options
author | Mohsin Kazmi <sykazmi@cisco.com> | 2022-03-31 21:59:15 +0000 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2022-04-08 16:17:49 +0000 |
commit | 90998bc00253730fc640d51e9995e71c2abbd6d0 (patch) | |
tree | 9ce9e907902ebde860ecc023d8306a08ccf569dd /src/plugins/dpdk/device | |
parent | bf91b48cbba65336de2043028f54b4b813325f3d (diff) |
dpdk: add multi-txq support
Type: improvement
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Change-Id: I9f061a05d947bc2867e1b962bf0522ad344bcc1a
Diffstat (limited to 'src/plugins/dpdk/device')
-rw-r--r-- | src/plugins/dpdk/device/common.c | 4 | ||||
-rw-r--r-- | src/plugins/dpdk/device/device.c | 23 | ||||
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 1 | ||||
-rw-r--r-- | src/plugins/dpdk/device/init.c | 16 |
4 files changed, 31 insertions, 13 deletions
diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c index f543723126f..a37659508dc 100644 --- a/src/plugins/dpdk/device/common.c +++ b/src/plugins/dpdk/device/common.c @@ -58,7 +58,6 @@ dpdk_device_setup (dpdk_device_t * xd) { vlib_main_t *vm = vlib_get_main (); vnet_main_t *vnm = vnet_get_main (); - vlib_thread_main_t *tm = vlib_get_thread_main (); vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, xd->sw_if_index); vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->hw_if_index); u16 buf_sz = vlib_buffer_get_default_data_size (vm); @@ -222,8 +221,7 @@ retry: if (rv < 0) dpdk_device_error (xd, "rte_eth_tx_queue_setup", rv); - if (xd->conf.n_tx_queues < tm->n_vlib_mains) - clib_spinlock_init (&vec_elt (xd->tx_queues, j).lock); + clib_spinlock_init (&vec_elt (xd->tx_queues, j).lock); } vec_validate_aligned (xd->rx_queues, xd->conf.n_rx_queues - 1, diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index b6a048e8ab9..1d97eee8055 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -152,28 +152,28 @@ dpdk_validate_rte_mbuf (vlib_main_t * vm, vlib_buffer_t * b, * support multiple queues. It returns the number of packets untransmitted * If all packets are transmitted (the normal case), the function returns 0. */ -static_always_inline - u32 tx_burst_vector_internal (vlib_main_t * vm, - dpdk_device_t * xd, - struct rte_mbuf **mb, u32 n_left) +static_always_inline u32 +tx_burst_vector_internal (vlib_main_t *vm, dpdk_device_t *xd, + struct rte_mbuf **mb, u32 n_left, int queue_id, + u8 is_shared) { dpdk_tx_queue_t *txq; u32 n_retry; int n_sent = 0; - int queue_id; n_retry = 16; - queue_id = vm->thread_index % xd->conf.n_tx_queues; txq = vec_elt_at_index (xd->tx_queues, queue_id); do { - clib_spinlock_lock_if_init (&txq->lock); + if (is_shared) + clib_spinlock_lock (&txq->lock); /* no wrap, transmit in one burst */ n_sent = rte_eth_tx_burst (xd->port_id, queue_id, mb, n_left); - clib_spinlock_unlock_if_init (&txq->lock); + if (is_shared) + clib_spinlock_unlock (&txq->lock); n_retry--; n_left -= n_sent; @@ -276,10 +276,12 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, dpdk_main_t *dm = &dpdk_main; vnet_interface_output_runtime_t *rd = (void *) node->runtime_data; dpdk_device_t *xd = vec_elt_at_index (dm->devices, rd->dev_instance); + vnet_hw_if_tx_frame_t *tf = vlib_frame_scalar_args (f); u32 n_packets = f->n_vectors; u32 n_left; u32 thread_index = vm->thread_index; - int queue_id = thread_index; + int queue_id = tf->queue_id; + u8 is_shared = tf->shared_queue; u32 tx_pkts = 0; dpdk_per_thread_data_t *ptd = vec_elt_at_index (dm->per_thread_data, thread_index); @@ -418,7 +420,8 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, /* transmit as many packets as possible */ tx_pkts = n_packets = mb - ptd->mbufs; - n_left = tx_burst_vector_internal (vm, xd, ptd->mbufs, n_packets); + n_left = tx_burst_vector_internal (vm, xd, ptd->mbufs, n_packets, queue_id, + is_shared); { /* If there is no callback then drop any non-transmitted packets */ diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index 6f3680c17a1..008c82df7b0 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -94,6 +94,7 @@ typedef struct { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); clib_spinlock_t lock; + u32 queue_index; } dpdk_tx_queue_t; typedef struct diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 13cecda9bf4..6d3b8643147 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -24,6 +24,7 @@ #include <vnet/vnet.h> #include <vnet/ethernet/ethernet.h> #include <vnet/interface/rx_queue_funcs.h> +#include <vnet/interface/tx_queue_funcs.h> #include <dpdk/buffer.h> #include <dpdk/device/dpdk.h> #include <dpdk/cryptodev/cryptodev.h> @@ -429,6 +430,8 @@ dpdk_lib_init (dpdk_main_t * dm) vec_validate_aligned (xd->rx_queues, xd->conf.n_rx_queues - 1, CLIB_CACHE_LINE_BYTES); + vec_validate_aligned (xd->tx_queues, xd->conf.n_tx_queues - 1, + CLIB_CACHE_LINE_BYTES); rte_eth_macaddr_get (port_id, (void *) addr); @@ -469,6 +472,19 @@ dpdk_lib_init (dpdk_main_t * dm) vnm, xd->hw_if_index, q, VNET_HW_IF_RXQ_THREAD_ANY); } + for (q = 0; q < xd->conf.n_tx_queues; q++) + { + dpdk_tx_queue_t *txq = vec_elt_at_index (xd->tx_queues, q); + txq->queue_index = + vnet_hw_if_register_tx_queue (vnm, xd->hw_if_index, q); + } + + for (q = 0; q < tm->n_vlib_mains; q++) + { + u32 qi = xd->tx_queues[q % xd->conf.n_tx_queues].queue_index; + vnet_hw_if_tx_queue_assign_thread (vnm, qi, q); + } + if (devconf->tso == DPDK_DEVICE_TSO_ON) { /*tcp_udp checksum must be enabled*/ |