aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammed Hawari <mohammed@hawari.fr>2024-10-30 19:17:07 +0100
committerFlorin Coras <florin.coras@gmail.com>2024-10-31 19:47:58 +0000
commitbd32d6234cad2af5bc220c6976aa84a758131427 (patch)
treee992d9597bec3891a45902bc85f529be74e381e4
parentbfad6b7a8f0a88531923e39f50b70cb5be6d52d7 (diff)
virtio: introduce the consistent-qp feature
In certain usecases related to Linux legacy pinning of flows on queue pairs, it is desirable that, for a given index, the rx and tx virtio queue be handled by the same worker. This change introduces a flag for virtio and tap interfaces that allow such a mapping. Example with two workers rxq 0 and txq 0 on worker 0 rxq 1 and txq 1 on worker 1 txq 2 on main thread Change-Id: I1b74a4788843fd1d0e8dcb4e9da30e609e088fe3 Signed-off-by: Mohammed Hawari <mohammed@hawari.fr> Type: improvement
-rw-r--r--src/vnet/devices/tap/cli.c2
-rw-r--r--src/vnet/devices/tap/tap.c3
-rw-r--r--src/vnet/devices/tap/tap.h19
-rw-r--r--src/vnet/devices/virtio/cli.c2
-rw-r--r--src/vnet/devices/virtio/pci.c7
-rw-r--r--src/vnet/devices/virtio/pci.h3
-rw-r--r--src/vnet/devices/virtio/virtio.c7
-rw-r--r--src/vnet/devices/virtio/virtio.h1
8 files changed, 29 insertions, 15 deletions
diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c
index 5c676d32d60..5738ef237b6 100644
--- a/src/vnet/devices/tap/cli.c
+++ b/src/vnet/devices/tap/cli.c
@@ -105,6 +105,8 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
args.tap_flags |= TAP_FLAG_PACKED;
else if (unformat (line_input, "in-order"))
args.tap_flags |= TAP_FLAG_IN_ORDER;
+ else if (unformat (line_input, "consistent-qp"))
+ args.tap_flags |= TAP_FLAG_CONSISTENT_QP;
else if (unformat (line_input, "hw-addr %U",
unformat_ethernet_address, args.mac_addr.bytes))
args.mac_addr_set = 1;
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index b0b0a3af13f..bb91200a525 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -212,6 +212,9 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
}
}
+ if (args->tap_flags & TAP_FLAG_CONSISTENT_QP)
+ vif->consistent_qp = 1;
+
/* if namespace is specified, all further netlink messages should be executed
* after we change our net namespace */
if (args->host_namespace)
diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h
index 1df2fb7e1ad..66f5576c5be 100644
--- a/src/vnet/devices/tap/tap.h
+++ b/src/vnet/devices/tap/tap.h
@@ -22,15 +22,16 @@
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif
-#define foreach_tapv2_flags \
- _ (GSO, 0) \
- _ (CSUM_OFFLOAD, 1) \
- _ (PERSIST, 2) \
- _ (ATTACH, 3) \
- _ (TUN, 4) \
- _ (GRO_COALESCE, 5) \
- _ (PACKED, 6) \
- _ (IN_ORDER, 7)
+#define foreach_tapv2_flags \
+ _ (GSO, 0) \
+ _ (CSUM_OFFLOAD, 1) \
+ _ (PERSIST, 2) \
+ _ (ATTACH, 3) \
+ _ (TUN, 4) \
+ _ (GRO_COALESCE, 5) \
+ _ (PACKED, 6) \
+ _ (IN_ORDER, 7) \
+ _ (CONSISTENT_QP, 8)
typedef enum
{
diff --git a/src/vnet/devices/virtio/cli.c b/src/vnet/devices/virtio/cli.c
index c4364600722..34c74ac91ac 100644
--- a/src/vnet/devices/virtio/cli.c
+++ b/src/vnet/devices/virtio/cli.c
@@ -64,6 +64,8 @@ virtio_pci_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
args.bind = VIRTIO_BIND_DEFAULT;
else if (unformat (line_input, "rss-enabled"))
args.rss_enabled = 1;
+ else if (unformat (line_input, "consistent-qp"))
+ args.virtio_flags |= VIRTIO_FLAG_CONSISTENT_QP;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c
index 140cdb94153..9562bdc6369 100644
--- a/src/vnet/devices/virtio/pci.c
+++ b/src/vnet/devices/virtio/pci.c
@@ -1418,9 +1418,10 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
if (args->virtio_flags & VIRTIO_FLAG_PACKED)
vif->is_packed = 1;
- if ((error =
- vlib_pci_device_open (vm, (vlib_pci_addr_t *) & vif->pci_addr,
- virtio_pci_device_ids, &h)))
+ if (args->virtio_flags & VIRTIO_FLAG_CONSISTENT_QP)
+ vif->consistent_qp = 1;
+ if ((error = vlib_pci_device_open (vm, (vlib_pci_addr_t *) &vif->pci_addr,
+ virtio_pci_device_ids, &h)))
{
args->rv = VNET_API_ERROR_INVALID_INTERFACE;
args->error =
diff --git a/src/vnet/devices/virtio/pci.h b/src/vnet/devices/virtio/pci.h
index 745ad6fce87..59778533316 100644
--- a/src/vnet/devices/virtio/pci.h
+++ b/src/vnet/devices/virtio/pci.h
@@ -283,7 +283,8 @@ typedef struct _virtio_pci_func
_ (PACKED, 3) \
_ (IN_ORDER, 4) \
_ (BUFFERING, 5) \
- _ (RSS, 6)
+ _ (RSS, 6) \
+ _ (CONSISTENT_QP, 7)
typedef enum
{
diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c
index 840936a43ff..682ec32ceff 100644
--- a/src/vnet/devices/virtio/virtio.c
+++ b/src/vnet/devices/virtio/virtio.c
@@ -294,6 +294,8 @@ virtio_vring_set_tx_queues (vlib_main_t *vm, virtio_if_t *vif)
{
vnet_main_t *vnm = vnet_get_main ();
vnet_virtio_vring_t *vring;
+ uword n_threads = vlib_get_n_threads ();
+ u8 consistent = vif->consistent_qp;
vec_foreach (vring, vif->txq_vrings)
{
@@ -308,10 +310,11 @@ virtio_vring_set_tx_queues (vlib_main_t *vm, virtio_if_t *vif)
return;
}
- for (u32 j = 0; j < vlib_get_n_threads (); j++)
+ for (u32 j = 0; j < n_threads; j++)
{
u32 qi = vif->txq_vrings[j % vif->num_txqs].queue_index;
- vnet_hw_if_tx_queue_assign_thread (vnm, qi, j);
+ vnet_hw_if_tx_queue_assign_thread (vnm, qi,
+ (j + consistent) % n_threads);
}
vnet_hw_if_update_runtime_data (vnm, vif->hw_if_index);
diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h
index a8e258884a4..fb72051ce45 100644
--- a/src/vnet/devices/virtio/virtio.h
+++ b/src/vnet/devices/virtio/virtio.h
@@ -213,6 +213,7 @@ typedef struct
};
const virtio_pci_func_t *virtio_pci_func;
int is_packed;
+ u8 consistent_qp : 1;
} virtio_if_t;
typedef struct