aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-10-29 14:00:43 +0000
committerPeter Maydell <peter.maydell@linaro.org>2024-10-29 14:00:43 +0000
commit58d49b5895f2e0b5cfe4b2901bf24f3320b74f29 (patch)
tree6828c87ad4dc5812484b57c5d13506fd9019132e /hw
parentfdf250e5a37830615e324017cb3a503e84b3712c (diff)
parentcd76e8fcbe1a340776ae61b4e182be3a45b26219 (diff)
downloadqemu-58d49b5895f2e0b5cfe4b2901bf24f3320b74f29.zip
qemu-58d49b5895f2e0b5cfe4b2901bf24f3320b74f29.tar.gz
qemu-58d49b5895f2e0b5cfe4b2901bf24f3320b74f29.tar.bz2
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging
# -----BEGIN PGP SIGNATURE----- # # iQEzBAABCAAdFiEEIV1G9IJGaJ7HfzVi7wSWWzmNYhEFAmcglKYACgkQ7wSWWzmN # YhEm/wf/cYA7i3asKMUoYqlff5mBiY3aFCWzTR5qHLBcWfnB33f9FYpAW6RgDwMa # 3aFAJm1VZAynmUWgz+f537+e+7900M+P54zbD7kHCthAy7l/E7t9SkKNpe6jZHEA # P4hB09CSKm/TY1XtsFMvO5tkF9IgY51VEO+mZJesO1H2X2+3ulJYusx9fh/P6yST # bG8sbXr55v23R3z4UOovqfkuskPETwRh3qoiOLPPBy8CWkBVze8J+siC7HC+eFIo # KrQ+jhUYpIK8CAgHV09ZnlurLo6UZ0+vlo9IcJN+GQp/gsmg8OErjvzPdKKbynC/ # 1zjvkgyW27aHsei+baTMXGCE0P8dIw== # =6+yo # -----END PGP SIGNATURE----- # gpg: Signature made Tue 29 Oct 2024 07:54:14 GMT # gpg: using RSA key 215D46F48246689EC77F3562EF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" [marginal] # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * tag 'net-pull-request' of https://github.com/jasowang/qemu: virtio-net: Avoid indirection_table_mask overflow Fix calculation of minimum in colo_compare_tcp net: Check if nc is NULL in qemu_get_vnet_hdr_len() net/tap-win32: Fix gcc 14 format truncation errors chardev: finalize 'reconnect' deprecation net/stream: deprecate 'reconnect' in favor of 'reconnect-ms' hw/net: improve tracing of eBPF RSS setup ebpf: improve trace event coverage to all key operations hw/net: report errors from failing to use eBPF RSS FDs ebpf: add formal error reporting to all APIs ebpf: improve error trace events ebpf: drop redundant parameter checks in static methods hw/net: fix typo s/epbf/ebpf/ in virtio-net net: fix build when libbpf is disabled, but libxdp is enabled Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/net/trace-events8
-rw-r--r--hw/net/virtio-net.c75
2 files changed, 53 insertions, 30 deletions
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 4c66879..91a3d0c 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -394,9 +394,11 @@ virtio_net_announce_notify(void) ""
virtio_net_announce_timer(int round) "%d"
virtio_net_handle_announce(int round) "%d"
virtio_net_post_load_device(void)
-virtio_net_rss_disable(void)
-virtio_net_rss_error(const char *msg, uint32_t value) "%s, value 0x%08x"
-virtio_net_rss_enable(uint32_t p1, uint16_t p2, uint8_t p3) "hashes 0x%x, table of %d, key of %d"
+virtio_net_rss_load(void *nic, size_t nfds, void *fds) "nic=%p nfds=%zu fds=%p"
+virtio_net_rss_attach_ebpf(void *nic, int prog_fd) "nic=%p prog-fd=%d"
+virtio_net_rss_disable(void *nic) "nic=%p"
+virtio_net_rss_error(void *nic, const char *msg, uint32_t value) "nic=%p msg=%s, value 0x%08x"
+virtio_net_rss_enable(void *nic, uint32_t p1, uint16_t p2, uint8_t p3) "nic=%p hashes 0x%x, table of %d, key of %d"
# tulip.c
tulip_reg_write(uint64_t addr, const char *name, int size, uint64_t val) "addr 0x%02"PRIx64" (%s) size %d value 0x%08"PRIx64
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index fb84d14..f2104ed 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1241,6 +1241,7 @@ static bool virtio_net_attach_ebpf_to_backend(NICState *nic, int prog_fd)
return false;
}
+ trace_virtio_net_rss_attach_ebpf(nic, prog_fd);
return nc->info->set_steering_ebpf(nc, prog_fd);
}
@@ -1254,7 +1255,7 @@ static void rss_data_to_rss_config(struct VirtioNetRssData *data,
config->default_queue = data->default_queue;
}
-static bool virtio_net_attach_epbf_rss(VirtIONet *n)
+static bool virtio_net_attach_ebpf_rss(VirtIONet *n)
{
struct EBPFRSSConfig config = {};
@@ -1265,7 +1266,8 @@ 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)) {
+ n->rss_data.indirections_table, n->rss_data.key,
+ NULL)) {
return false;
}
@@ -1276,7 +1278,7 @@ static bool virtio_net_attach_epbf_rss(VirtIONet *n)
return true;
}
-static void virtio_net_detach_epbf_rss(VirtIONet *n)
+static void virtio_net_detach_ebpf_rss(VirtIONet *n)
{
virtio_net_attach_ebpf_to_backend(n->nic, -1);
}
@@ -1286,8 +1288,8 @@ 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)) {
+ virtio_net_detach_ebpf_rss(n);
+ } else if (!virtio_net_attach_ebpf_rss(n)) {
if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
warn_report("Can't load eBPF RSS for vhost");
} else {
@@ -1296,12 +1298,13 @@ static void virtio_net_commit_rss_config(VirtIONet *n)
}
}
- trace_virtio_net_rss_enable(n->rss_data.hash_types,
+ trace_virtio_net_rss_enable(n,
+ 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();
+ virtio_net_detach_ebpf_rss(n);
+ trace_virtio_net_rss_disable(n);
}
}
@@ -1315,28 +1318,27 @@ static void virtio_net_disable_rss(VirtIONet *n)
virtio_net_commit_rss_config(n);
}
-static bool virtio_net_load_ebpf_fds(VirtIONet *n)
+static bool virtio_net_load_ebpf_fds(VirtIONet *n, Error **errp)
{
int fds[EBPF_RSS_MAX_FDS] = { [0 ... EBPF_RSS_MAX_FDS - 1] = -1};
int ret = true;
int i = 0;
if (n->nr_ebpf_rss_fds != EBPF_RSS_MAX_FDS) {
- warn_report("Expected %d file descriptors but got %d",
- EBPF_RSS_MAX_FDS, n->nr_ebpf_rss_fds);
- return false;
- }
+ error_setg(errp, "Expected %d file descriptors but got %d",
+ EBPF_RSS_MAX_FDS, n->nr_ebpf_rss_fds);
+ return false;
+ }
for (i = 0; i < n->nr_ebpf_rss_fds; i++) {
- fds[i] = monitor_fd_param(monitor_cur(), n->ebpf_rss_fds[i],
- &error_warn);
+ fds[i] = monitor_fd_param(monitor_cur(), n->ebpf_rss_fds[i], errp);
if (fds[i] < 0) {
ret = false;
goto exit;
}
}
- ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3]);
+ ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3], errp);
exit:
if (!ret) {
@@ -1348,13 +1350,16 @@ exit:
return ret;
}
-static bool virtio_net_load_ebpf(VirtIONet *n)
+static bool virtio_net_load_ebpf(VirtIONet *n, Error **errp)
{
bool ret = false;
if (virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
- if (!(n->ebpf_rss_fds && virtio_net_load_ebpf_fds(n))) {
- ret = ebpf_rss_load(&n->ebpf_rss);
+ trace_virtio_net_rss_load(n, n->nr_ebpf_rss_fds, n->ebpf_rss_fds);
+ if (n->ebpf_rss_fds) {
+ ret = virtio_net_load_ebpf_fds(n, errp);
+ } else {
+ ret = ebpf_rss_load(&n->ebpf_rss, errp);
}
}
@@ -1401,17 +1406,17 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
n->rss_data.hash_types = virtio_ldl_p(vdev, &cfg.hash_types);
n->rss_data.indirections_len =
virtio_lduw_p(vdev, &cfg.indirection_table_mask);
- n->rss_data.indirections_len++;
if (!do_rss) {
- n->rss_data.indirections_len = 1;
+ n->rss_data.indirections_len = 0;
}
- if (!is_power_of_2(n->rss_data.indirections_len)) {
- err_msg = "Invalid size of indirection table";
+ if (n->rss_data.indirections_len >= VIRTIO_NET_RSS_MAX_TABLE_LEN) {
+ err_msg = "Too large indirection table";
err_value = n->rss_data.indirections_len;
goto error;
}
- if (n->rss_data.indirections_len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
- err_msg = "Too large indirection table";
+ n->rss_data.indirections_len++;
+ if (!is_power_of_2(n->rss_data.indirections_len)) {
+ err_msg = "Invalid size of indirection table";
err_value = n->rss_data.indirections_len;
goto error;
}
@@ -1482,7 +1487,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
virtio_net_commit_rss_config(n);
return queue_pairs;
error:
- trace_virtio_net_rss_error(err_msg, err_value);
+ trace_virtio_net_rss_error(n, err_msg, err_value);
virtio_net_disable_rss(n);
return 0;
}
@@ -3760,7 +3765,23 @@ 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);
+ Error *err = NULL;
+ if (!virtio_net_load_ebpf(n, &err)) {
+ /*
+ * If user explicitly gave QEMU RSS FDs to use, then
+ * failing to use them must be considered a fatal
+ * error. If no RSS FDs were provided, QEMU is trying
+ * eBPF on a "best effort" basis only, so report a
+ * warning and allow fallback to software RSS.
+ */
+ if (n->ebpf_rss_fds) {
+ error_propagate(errp, err);
+ } else {
+ warn_report("unable to load eBPF RSS: %s",
+ error_get_pretty(err));
+ error_free(err);
+ }
+ }
}
}