|
@@ -1316,28 +1316,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], NULL);
|
|
|
+ ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3], errp);
|
|
|
|
|
|
exit:
|
|
|
if (!ret) {
|
|
@@ -1349,13 +1348,15 @@ 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, NULL);
|
|
|
+ if (n->ebpf_rss_fds) {
|
|
|
+ ret = virtio_net_load_ebpf_fds(n, errp);
|
|
|
+ } else {
|
|
|
+ ret = ebpf_rss_load(&n->ebpf_rss, errp);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3761,7 +3762,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);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|