* [PATCH 1/6] tap: Fix virtio-net header buffer size
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
@ 2023-10-08 5:29 ` Akihiko Odaki
2023-10-08 6:25 ` Michael S. Tsirkin
2023-10-08 5:29 ` [PATCH 2/6] virtio-net: Copy header only when necessary Akihiko Odaki
` (4 subsequent siblings)
5 siblings, 1 reply; 7+ messages in thread
From: Akihiko Odaki @ 2023-10-08 5:29 UTC (permalink / raw)
Cc: Akihiko Odaki, Jason Wang, open list:All patches CC here
The largest possible virtio-net header is struct virtio_net_hdr_v1_hash.
Fixes: fbbdbddec0 ("tap: allow extended virtio header with hash info")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
net/tap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index c6639d9f20..ea46feeaa8 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -118,7 +118,7 @@ static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
TAPState *s = DO_UPCAST(TAPState, nc, nc);
const struct iovec *iovp = iov;
struct iovec iov_copy[iovcnt + 1];
- struct virtio_net_hdr_mrg_rxbuf hdr = { };
+ struct virtio_net_hdr_v1_hash hdr = { };
if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
iov_copy[0].iov_base = &hdr;
@@ -136,7 +136,7 @@ static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, size_t si
TAPState *s = DO_UPCAST(TAPState, nc, nc);
struct iovec iov[2];
int iovcnt = 0;
- struct virtio_net_hdr_mrg_rxbuf hdr = { };
+ struct virtio_net_hdr_v1_hash hdr = { };
if (s->host_vnet_hdr_len) {
iov[iovcnt].iov_base = &hdr;
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] virtio-net: Copy header only when necessary
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
2023-10-08 5:29 ` [PATCH 1/6] tap: Fix virtio-net header buffer size Akihiko Odaki
@ 2023-10-08 5:29 ` Akihiko Odaki
2023-10-08 5:29 ` [PATCH 3/6] virtio-net: Disable RSS on reset Akihiko Odaki
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2023-10-08 5:29 UTC (permalink / raw)
Cc: Akihiko Odaki, Michael S. Tsirkin, Jason Wang,
open list:All patches CC here
It is necessary to copy the header only for byte swapping. Worse, when
byte swapping is not needed, the header can be larger than the buffer
due to VIRTIO_NET_F_HASH_REPORT, which results in buffer overflow.
Copy the header only when byte swapping is needed.
Fixes: e22f0603fb ("virtio-net: reference implementation of hash report")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9a93a2df01..1ba748c964 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -361,7 +361,8 @@ static void virtio_net_vnet_endian_status(VirtIONet *n, uint8_t status)
* can't do it, we fallback onto fixing the headers in the core
* virtio-net code.
*/
- n->needs_vnet_hdr_swap = virtio_net_set_vnet_endian(vdev, n->nic->ncs,
+ n->needs_vnet_hdr_swap = n->has_vnet_hdr &&
+ virtio_net_set_vnet_endian(vdev, n->nic->ncs,
queue_pairs, true);
} else if (virtio_net_started(n, vdev->status)) {
/* After using the device, we need to reset the network backend to
@@ -2690,7 +2691,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
return -EINVAL;
}
- if (n->has_vnet_hdr) {
+ if (n->needs_vnet_hdr_swap) {
if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) <
n->guest_hdr_len) {
virtio_error(vdev, "virtio-net header incorrect");
@@ -2698,19 +2699,16 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
g_free(elem);
return -EINVAL;
}
- if (n->needs_vnet_hdr_swap) {
- virtio_net_hdr_swap(vdev, (void *) &mhdr);
- sg2[0].iov_base = &mhdr;
- sg2[0].iov_len = n->guest_hdr_len;
- out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1,
- out_sg, out_num,
- n->guest_hdr_len, -1);
- if (out_num == VIRTQUEUE_MAX_SIZE) {
- goto drop;
- }
- out_num += 1;
- out_sg = sg2;
+ virtio_net_hdr_swap(vdev, (void *) &mhdr);
+ sg2[0].iov_base = &mhdr;
+ sg2[0].iov_len = n->guest_hdr_len;
+ out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, out_sg, out_num,
+ n->guest_hdr_len, -1);
+ if (out_num == VIRTQUEUE_MAX_SIZE) {
+ goto drop;
}
+ out_num += 1;
+ out_sg = sg2;
}
/*
* If host wants to see the guest header as is, we can
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] virtio-net: Disable RSS on reset
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
2023-10-08 5:29 ` [PATCH 1/6] tap: Fix virtio-net header buffer size Akihiko Odaki
2023-10-08 5:29 ` [PATCH 2/6] virtio-net: Copy header only when necessary Akihiko Odaki
@ 2023-10-08 5:29 ` Akihiko Odaki
2023-10-08 5:29 ` [PATCH 4/6] virtio-net: Unify the logic to update NIC state for RSS Akihiko Odaki
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2023-10-08 5:29 UTC (permalink / raw)
Cc: Akihiko Odaki, Michael S. Tsirkin, Jason Wang,
open list:All patches CC here
RSS is disabled by default.
Fixes: 590790297c ("virtio-net: implement RSS configuration command")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 70 +++++++++++++++++++++++----------------------
1 file changed, 36 insertions(+), 34 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 1ba748c964..83bac9a98a 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -601,40 +601,6 @@ static void virtio_net_queue_enable(VirtIODevice *vdev, uint32_t queue_index)
}
}
-static void virtio_net_reset(VirtIODevice *vdev)
-{
- VirtIONet *n = VIRTIO_NET(vdev);
- int i;
-
- /* Reset back to compatibility mode */
- n->promisc = 1;
- n->allmulti = 0;
- n->alluni = 0;
- n->nomulti = 0;
- n->nouni = 0;
- n->nobcast = 0;
- /* multiqueue is disabled by default */
- n->curr_queue_pairs = 1;
- timer_del(n->announce_timer.tm);
- n->announce_timer.round = 0;
- n->status &= ~VIRTIO_NET_S_ANNOUNCE;
-
- /* Flush any MAC and VLAN filter table state */
- n->mac_table.in_use = 0;
- n->mac_table.first_multi = 0;
- n->mac_table.multi_overflow = 0;
- n->mac_table.uni_overflow = 0;
- memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
- memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac));
- qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
- memset(n->vlans, 0, MAX_VLAN >> 3);
-
- /* Flush any async TX */
- for (i = 0; i < n->max_queue_pairs; i++) {
- flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i));
- }
-}
-
static void peer_test_vnet_hdr(VirtIONet *n)
{
NetClientState *nc = qemu_get_queue(n->nic);
@@ -3789,6 +3755,42 @@ static void virtio_net_device_unrealize(DeviceState *dev)
virtio_cleanup(vdev);
}
+static void virtio_net_reset(VirtIODevice *vdev)
+{
+ VirtIONet *n = VIRTIO_NET(vdev);
+ int i;
+
+ /* Reset back to compatibility mode */
+ n->promisc = 1;
+ n->allmulti = 0;
+ n->alluni = 0;
+ n->nomulti = 0;
+ n->nouni = 0;
+ n->nobcast = 0;
+ /* multiqueue is disabled by default */
+ n->curr_queue_pairs = 1;
+ timer_del(n->announce_timer.tm);
+ n->announce_timer.round = 0;
+ n->status &= ~VIRTIO_NET_S_ANNOUNCE;
+
+ /* Flush any MAC and VLAN filter table state */
+ n->mac_table.in_use = 0;
+ n->mac_table.first_multi = 0;
+ n->mac_table.multi_overflow = 0;
+ n->mac_table.uni_overflow = 0;
+ memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
+ memcpy(&n->mac[0], &n->nic->conf->macaddr, sizeof(n->mac));
+ qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
+ memset(n->vlans, 0, MAX_VLAN >> 3);
+
+ /* Flush any async TX */
+ for (i = 0; i < n->max_queue_pairs; i++) {
+ flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i));
+ }
+
+ virtio_net_disable_rss(n);
+}
+
static void virtio_net_instance_init(Object *obj)
{
VirtIONet *n = VIRTIO_NET(obj);
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] virtio-net: Unify the logic to update NIC state for RSS
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
` (2 preceding siblings ...)
2023-10-08 5:29 ` [PATCH 3/6] virtio-net: Disable RSS on reset Akihiko Odaki
@ 2023-10-08 5:29 ` Akihiko Odaki
2023-10-08 5:29 ` [PATCH 5/6] virtio-net: Return an error when vhost cannot enable RSS Akihiko Odaki
2023-10-08 5:29 ` [PATCH 6/6] virtio-net: Do not clear VIRTIO_NET_F_RSS Akihiko Odaki
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2023-10-08 5:29 UTC (permalink / raw)
Cc: Akihiko Odaki, Michael S. Tsirkin, Jason Wang,
open list:All patches CC here
The code to attach or detach the eBPF program to RSS were duplicated so
unify them into one function to save some code.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 90 ++++++++++++++++++---------------------------
1 file changed, 36 insertions(+), 54 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 83bac9a98a..3c3440ab72 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1212,18 +1212,6 @@ static int virtio_net_handle_announce(VirtIONet *n, uint8_t cmd,
}
}
-static void virtio_net_detach_epbf_rss(VirtIONet *n);
-
-static void virtio_net_disable_rss(VirtIONet *n)
-{
- if (n->rss_data.enabled) {
- trace_virtio_net_rss_disable();
- }
- n->rss_data.enabled = false;
-
- virtio_net_detach_epbf_rss(n);
-}
-
static bool virtio_net_attach_ebpf_to_backend(NICState *nic, int prog_fd)
{
NetClientState *nc = qemu_get_peer(qemu_get_queue(nic), 0);
@@ -1271,6 +1259,40 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
virtio_net_attach_ebpf_to_backend(n->nic, -1);
}
+static void virtio_net_commit_rss_config(VirtIONet *n)
+{
+ if (n->rss_data.enabled) {
+ n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
+ if (n->rss_data.populate_hash) {
+ virtio_net_detach_epbf_rss(n);
+ } else if (!virtio_net_attach_epbf_rss(n)) {
+ if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
+ warn_report("Can't use eBPF RSS for vhost");
+ } else {
+ warn_report("Can't use eBPF RSS - fallback to software RSS");
+ n->rss_data.enabled_software_rss = true;
+ }
+ }
+
+ trace_virtio_net_rss_enable(n->rss_data.hash_types,
+ n->rss_data.indirections_len,
+ sizeof(n->rss_data.key));
+ } else {
+ virtio_net_detach_epbf_rss(n);
+ trace_virtio_net_rss_disable();
+ }
+}
+
+static void virtio_net_disable_rss(VirtIONet *n)
+{
+ if (!n->rss_data.enabled) {
+ return;
+ }
+
+ n->rss_data.enabled = false;
+ virtio_net_commit_rss_config(n);
+}
+
static bool virtio_net_load_ebpf(VirtIONet *n)
{
if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
@@ -1399,28 +1421,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
goto error;
}
n->rss_data.enabled = true;
-
- if (!n->rss_data.populate_hash) {
- if (!virtio_net_attach_epbf_rss(n)) {
- /* EBPF must be loaded for vhost */
- if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
- warn_report("Can't load eBPF RSS for vhost");
- goto error;
- }
- /* fallback to software RSS */
- warn_report("Can't load eBPF RSS - fallback to software RSS");
- n->rss_data.enabled_software_rss = true;
- }
- } else {
- /* use software RSS for hash populating */
- /* and detach eBPF if was loaded before */
- virtio_net_detach_epbf_rss(n);
- n->rss_data.enabled_software_rss = true;
- }
-
- trace_virtio_net_rss_enable(n->rss_data.hash_types,
- n->rss_data.indirections_len,
- temp.b);
+ virtio_net_commit_rss_config(n);
return queue_pairs;
error:
trace_virtio_net_rss_error(err_msg, err_value);
@@ -3016,26 +3017,7 @@ static int virtio_net_post_load_device(void *opaque, int version_id)
}
}
- if (n->rss_data.enabled) {
- n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
- if (!n->rss_data.populate_hash) {
- if (!virtio_net_attach_epbf_rss(n)) {
- if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
- warn_report("Can't post-load eBPF RSS for vhost");
- } else {
- warn_report("Can't post-load eBPF RSS - "
- "fallback to software RSS");
- n->rss_data.enabled_software_rss = true;
- }
- }
- }
-
- trace_virtio_net_rss_enable(n->rss_data.hash_types,
- n->rss_data.indirections_len,
- sizeof(n->rss_data.key));
- } else {
- trace_virtio_net_rss_disable();
- }
+ virtio_net_commit_rss_config(n);
return 0;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] virtio-net: Return an error when vhost cannot enable RSS
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
` (3 preceding siblings ...)
2023-10-08 5:29 ` [PATCH 4/6] virtio-net: Unify the logic to update NIC state for RSS Akihiko Odaki
@ 2023-10-08 5:29 ` Akihiko Odaki
2023-10-08 5:29 ` [PATCH 6/6] virtio-net: Do not clear VIRTIO_NET_F_RSS Akihiko Odaki
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2023-10-08 5:29 UTC (permalink / raw)
Cc: Akihiko Odaki, Jason Wang, Andrew Melnychenko, Yuri Benditovich,
Michael S. Tsirkin, open list:All patches CC here
vhost requires eBPF for RSS. Even when eBPF is not available, virtio-net
reported RSS availability, and raised a warning only after the
guest requested RSS, and the guest could not know that RSS is not
available.
Check RSS availability during device realization and return an error
if RSS is requested but not available. Assert RSS availability when
the guest actually requests the feature.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
| 2 +-
| 4 +-
| 68 +++++++++-----------------
hw/net/virtio-net.c | 114 +++++++++++++++++++++----------------------
4 files changed, 82 insertions(+), 106 deletions(-)
--git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
index bf3f2572c7..1128173572 100644
--- a/ebpf/ebpf_rss.h
+++ b/ebpf/ebpf_rss.h
@@ -36,7 +36,7 @@ bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx);
bool ebpf_rss_load(struct EBPFRSSContext *ctx);
-bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
+void ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
uint16_t *indirections_table, uint8_t *toeplitz_key);
void ebpf_rss_unload(struct EBPFRSSContext *ctx);
--git a/ebpf/ebpf_rss-stub.c b/ebpf/ebpf_rss-stub.c
index e71e229190..525b358597 100644
--- a/ebpf/ebpf_rss-stub.c
+++ b/ebpf/ebpf_rss-stub.c
@@ -28,10 +28,10 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
return false;
}
-bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
+void ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
uint16_t *indirections_table, uint8_t *toeplitz_key)
{
- return false;
+ g_assert_not_reached();
}
void ebpf_rss_unload(struct EBPFRSSContext *ctx)
--git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
index cee658c158..6cdf82d059 100644
--- a/ebpf/ebpf_rss.c
+++ b/ebpf/ebpf_rss.c
@@ -74,42 +74,32 @@ error:
return false;
}
-static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
+static void ebpf_rss_set_config(struct EBPFRSSContext *ctx,
struct EBPFRSSConfig *config)
{
uint32_t map_key = 0;
- if (!ebpf_rss_is_loaded(ctx)) {
- return false;
- }
- if (bpf_map_update_elem(ctx->map_configuration,
- &map_key, config, 0) < 0) {
- return false;
- }
- return true;
+ assert(ebpf_rss_is_loaded(ctx));
+ assert(!bpf_map_update_elem(ctx->map_configuration, &map_key, config, 0));
}
-static bool ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
+static void ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
uint16_t *indirections_table,
size_t len)
{
uint32_t i = 0;
- if (!ebpf_rss_is_loaded(ctx) || indirections_table == NULL ||
- len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
- return false;
- }
+ assert(ebpf_rss_is_loaded(ctx));
+ assert(indirections_table);
+ assert(len <= VIRTIO_NET_RSS_MAX_TABLE_LEN);
for (; i < len; ++i) {
- if (bpf_map_update_elem(ctx->map_indirections_table, &i,
- indirections_table + i, 0) < 0) {
- return false;
- }
+ assert(!bpf_map_update_elem(ctx->map_indirections_table, &i,
+ indirections_table + i, 0));
}
- return true;
}
-static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
+static void ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
uint8_t *toeplitz_key)
{
uint32_t map_key = 0;
@@ -117,41 +107,29 @@ static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
/* prepare toeplitz key */
uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};
- if (!ebpf_rss_is_loaded(ctx) || toeplitz_key == NULL) {
- return false;
- }
+ assert(ebpf_rss_is_loaded(ctx));
+ assert(toeplitz_key);
+
memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_MAX_KEY_SIZE);
*(uint32_t *)toe = ntohl(*(uint32_t *)toe);
- if (bpf_map_update_elem(ctx->map_toeplitz_key, &map_key, toe,
- 0) < 0) {
- return false;
- }
- return true;
+ assert(!bpf_map_update_elem(ctx->map_toeplitz_key, &map_key, toe, 0));
}
-bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
+void ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
uint16_t *indirections_table, uint8_t *toeplitz_key)
{
- if (!ebpf_rss_is_loaded(ctx) || config == NULL ||
- indirections_table == NULL || toeplitz_key == NULL) {
- return false;
- }
-
- if (!ebpf_rss_set_config(ctx, config)) {
- return false;
- }
+ assert(ebpf_rss_is_loaded(ctx));
+ assert(config);
+ assert(indirections_table);
+ assert(toeplitz_key);
- if (!ebpf_rss_set_indirections_table(ctx, indirections_table,
- config->indirections_len)) {
- return false;
- }
+ ebpf_rss_set_config(ctx, config);
- if (!ebpf_rss_set_toepliz_key(ctx, toeplitz_key)) {
- return false;
- }
+ ebpf_rss_set_indirections_table(ctx, indirections_table,
+ config->indirections_len);
- return true;
+ ebpf_rss_set_toepliz_key(ctx, toeplitz_key);
}
void ebpf_rss_unload(struct EBPFRSSContext *ctx)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3c3440ab72..05f9abdbcd 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1242,14 +1242,10 @@ static bool virtio_net_attach_epbf_rss(VirtIONet *n)
rss_data_to_rss_config(&n->rss_data, &config);
- if (!ebpf_rss_set_all(&n->ebpf_rss, &config,
- n->rss_data.indirections_table, n->rss_data.key)) {
- return false;
- }
+ ebpf_rss_set_all(&n->ebpf_rss, &config,
+ n->rss_data.indirections_table, n->rss_data.key);
- if (!virtio_net_attach_ebpf_to_backend(n->nic, n->ebpf_rss.program_fd)) {
- return false;
- }
+ assert(virtio_net_attach_ebpf_to_backend(n->nic, n->ebpf_rss.program_fd));
return true;
}
@@ -1266,12 +1262,7 @@ static void virtio_net_commit_rss_config(VirtIONet *n)
if (n->rss_data.populate_hash) {
virtio_net_detach_epbf_rss(n);
} else if (!virtio_net_attach_epbf_rss(n)) {
- if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
- warn_report("Can't use eBPF RSS for vhost");
- } else {
- warn_report("Can't use eBPF RSS - fallback to software RSS");
- n->rss_data.enabled_software_rss = true;
- }
+ n->rss_data.enabled_software_rss = true;
}
trace_virtio_net_rss_enable(n->rss_data.hash_types,
@@ -3514,6 +3505,50 @@ static bool failover_hide_primary_device(DeviceListener *listener,
return qatomic_read(&n->failover_primary_hidden);
}
+static void virtio_net_device_unrealize(DeviceState *dev)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtIONet *n = VIRTIO_NET(dev);
+ int i, max_queue_pairs;
+
+ if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
+ virtio_net_unload_ebpf(n);
+ }
+
+ /* This will stop vhost backend if appropriate. */
+ virtio_net_set_status(vdev, 0);
+
+ g_free(n->netclient_name);
+ n->netclient_name = NULL;
+ g_free(n->netclient_type);
+ n->netclient_type = NULL;
+
+ g_free(n->mac_table.macs);
+ g_free(n->vlans);
+
+ if (n->failover) {
+ qobject_unref(n->primary_opts);
+ device_listener_unregister(&n->primary_listener);
+ remove_migration_state_change_notifier(&n->migration_state);
+ } else {
+ assert(n->primary_opts == NULL);
+ }
+
+ max_queue_pairs = n->multiqueue ? n->max_queue_pairs : 1;
+ for (i = 0; i < max_queue_pairs; i++) {
+ virtio_net_del_queue(n, i);
+ }
+ /* delete also control vq */
+ virtio_del_queue(vdev, max_queue_pairs * 2);
+ qemu_announce_timer_del(&n->announce_timer, false);
+ g_free(n->vqs);
+ qemu_del_nic(n->nic);
+ virtio_net_rsc_cleanup(n);
+ g_free(n->rss_data.indirections_table);
+ net_rx_pkt_uninit(n->rx_pkt);
+ virtio_cleanup(vdev);
+}
+
static void virtio_net_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -3688,53 +3723,16 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
net_rx_pkt_init(&n->rx_pkt);
- if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
- virtio_net_load_ebpf(n);
- }
-}
-
-static void virtio_net_device_unrealize(DeviceState *dev)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- VirtIONet *n = VIRTIO_NET(dev);
- int i, max_queue_pairs;
-
- if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
- virtio_net_unload_ebpf(n);
- }
-
- /* This will stop vhost backend if appropriate. */
- virtio_net_set_status(vdev, 0);
-
- g_free(n->netclient_name);
- n->netclient_name = NULL;
- g_free(n->netclient_type);
- n->netclient_type = NULL;
-
- g_free(n->mac_table.macs);
- g_free(n->vlans);
-
- if (n->failover) {
- qobject_unref(n->primary_opts);
- device_listener_unregister(&n->primary_listener);
- remove_migration_state_change_notifier(&n->migration_state);
- } else {
- assert(n->primary_opts == NULL);
- }
+ if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS) &&
+ !virtio_net_load_ebpf(n)) {
+ if (get_vhost_net(nc->peer)) {
+ error_setg(errp, "Can't load eBPF RSS for vhost");
+ virtio_net_device_unrealize(dev);
+ return;
+ }
- max_queue_pairs = n->multiqueue ? n->max_queue_pairs : 1;
- for (i = 0; i < max_queue_pairs; i++) {
- virtio_net_del_queue(n, i);
+ warn_report_once("Can't load eBPF RSS - fallback to software RSS");
}
- /* delete also control vq */
- virtio_del_queue(vdev, max_queue_pairs * 2);
- qemu_announce_timer_del(&n->announce_timer, false);
- g_free(n->vqs);
- qemu_del_nic(n->nic);
- virtio_net_rsc_cleanup(n);
- g_free(n->rss_data.indirections_table);
- net_rx_pkt_uninit(n->rx_pkt);
- virtio_cleanup(vdev);
}
static void virtio_net_reset(VirtIODevice *vdev)
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] virtio-net: Do not clear VIRTIO_NET_F_RSS
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
` (4 preceding siblings ...)
2023-10-08 5:29 ` [PATCH 5/6] virtio-net: Return an error when vhost cannot enable RSS Akihiko Odaki
@ 2023-10-08 5:29 ` Akihiko Odaki
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2023-10-08 5:29 UTC (permalink / raw)
Cc: Akihiko Odaki, Michael S. Tsirkin, Jason Wang,
open list:All patches CC here
Even if eBPF is not available, virtio-net can perform RSS on the
user-space if vhost is disabled although such a configuration results in
a warning. If vhost is enabled, the configuration will be rejected when
realizing the device. Therefore, VIRTIO_NET_F_RSS should not be cleared
even if eBPF is not loaded.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 05f9abdbcd..3bb4bf136d 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -775,9 +775,6 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
return features;
}
- if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
- }
features = vhost_net_get_features(get_vhost_net(nc->peer), features);
vdev->backend_features = features;
--
2.42.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/6] tap: Fix virtio-net header buffer size
2023-10-08 5:29 ` [PATCH 1/6] tap: Fix virtio-net header buffer size Akihiko Odaki
@ 2023-10-08 6:25 ` Michael S. Tsirkin
0 siblings, 0 replies; 7+ messages in thread
From: Michael S. Tsirkin @ 2023-10-08 6:25 UTC (permalink / raw)
To: Akihiko Odaki; +Cc: Jason Wang, open list:All patches CC here
On Sun, Oct 08, 2023 at 02:29:10PM +0900, Akihiko Odaki wrote:
> The largest possible virtio-net header is struct virtio_net_hdr_v1_hash.
>
> Fixes: fbbdbddec0 ("tap: allow extended virtio header with hash info")
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
This thread is malformed BTW: cover letter seems to be
missing on list.
> ---
> net/tap.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/tap.c b/net/tap.c
> index c6639d9f20..ea46feeaa8 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -118,7 +118,7 @@ static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
> TAPState *s = DO_UPCAST(TAPState, nc, nc);
> const struct iovec *iovp = iov;
> struct iovec iov_copy[iovcnt + 1];
> - struct virtio_net_hdr_mrg_rxbuf hdr = { };
> + struct virtio_net_hdr_v1_hash hdr = { };
>
> if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
> iov_copy[0].iov_base = &hdr;
> @@ -136,7 +136,7 @@ static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, size_t si
> TAPState *s = DO_UPCAST(TAPState, nc, nc);
> struct iovec iov[2];
> int iovcnt = 0;
> - struct virtio_net_hdr_mrg_rxbuf hdr = { };
> + struct virtio_net_hdr_v1_hash hdr = { };
>
> if (s->host_vnet_hdr_len) {
> iov[iovcnt].iov_base = &hdr;
> --
> 2.42.0
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-10-08 6:25 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20231008052917.145245-1-akihiko.odaki@daynix.com>
2023-10-08 5:29 ` [PATCH 1/6] tap: Fix virtio-net header buffer size Akihiko Odaki
2023-10-08 6:25 ` Michael S. Tsirkin
2023-10-08 5:29 ` [PATCH 2/6] virtio-net: Copy header only when necessary Akihiko Odaki
2023-10-08 5:29 ` [PATCH 3/6] virtio-net: Disable RSS on reset Akihiko Odaki
2023-10-08 5:29 ` [PATCH 4/6] virtio-net: Unify the logic to update NIC state for RSS Akihiko Odaki
2023-10-08 5:29 ` [PATCH 5/6] virtio-net: Return an error when vhost cannot enable RSS Akihiko Odaki
2023-10-08 5:29 ` [PATCH 6/6] virtio-net: Do not clear VIRTIO_NET_F_RSS Akihiko Odaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).