From nobody Fri Oct 10 17:22:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1610657467; cv=none; d=zohomail.com; s=zohoarc; b=Xe266nfGmE+GQpLfVYAIEd4dPdcNUvfS8bSDSqUs9sE84HYP5U+LHzSzR36vMRnwFrRNQ9qBE/bbfD5wIn0x7Tbdg4uNMl5/fP8wzIZEQxaK0CoTNCqi2RHtTgIToJu9KC+MMybwpioQNi/LJxORL6H6JX7SkFqmCYGN6RrdaIk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1610657467; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ZPaMBSaV2KC4x7hhUhbB1rSXPGJT23+noPGc9I7/G4Y=; b=aCLR16J88lMrDDmLiWX+FrbIBajjg4kJa4sVhGSuJYCsMqXDz3NeoykfU24zkgQPvvm045B3lu8uAiPEXk7i2gVLtqluPazLE8BxctWnzRXoVMQYTZlXrnUDND+sNgceTxmaJEnzMsoiAMtgYgC8oBBcVXfjmSxWi3vZVia8/I4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 161065746790654.794564862053676; Thu, 14 Jan 2021 12:51:07 -0800 (PST) Received: from localhost ([::1]:50078 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l09aE-0002lP-PA for importer@patchew.org; Thu, 14 Jan 2021 15:51:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33566) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l09SJ-0003kc-GO for qemu-devel@nongnu.org; Thu, 14 Jan 2021 15:42:56 -0500 Received: from mail-lj1-x22e.google.com ([2a00:1450:4864:20::22e]:34156) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1l09SC-0004kC-4J for qemu-devel@nongnu.org; Thu, 14 Jan 2021 15:42:55 -0500 Received: by mail-lj1-x22e.google.com with SMTP id m10so8005975lji.1 for ; Thu, 14 Jan 2021 12:42:46 -0800 (PST) Received: from navi.cosmonova.net.ua ([95.67.24.131]) by smtp.gmail.com with ESMTPSA id t20sm565833ljk.58.2021.01.14.12.42.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Jan 2021 12:42:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZPaMBSaV2KC4x7hhUhbB1rSXPGJT23+noPGc9I7/G4Y=; b=0JD4wfLIljA0fU9EGFq1KsVNGYcy8mJ447mvQ7AZJuT6gdgqA8ISs6eAVwhIXLNRx4 lcJyKGyExj671rMxMlgBmEvNdwE3Jx23Z83emiU6geXsr9sBqD2CV7X08+i+/rN+eWOx fM01gvY8tySx2WeWcoL4ySMAVDbbQRklB3ekck4746sGtzq6GCaNMx5Qz3+LL/xkLYjr LuZVs7Xb9dJmHr40gqv6Dj2LRKo3vo3ls6I58x7Ci4oBcFN4SiOFp1/Q2IDxxyaR/lpU ZwyQSqo74UGP2Ny5h6NU2f81RLKYleZDJuuRqk0vqROmCtvN9mAQsII6pYMyb/zM9YDn kbkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZPaMBSaV2KC4x7hhUhbB1rSXPGJT23+noPGc9I7/G4Y=; b=X9BmL0BubHqu8++0x690O9OFos8TnbM0sa1k0QhyQtwlLxvCrSJ6hlUjIMy1Bdf5VT Zp1v/sy0AJ9RNrJnqJ8GBTEgDVHAILlQh21vVucetkWtqRl9LPkI4z6iB+VwlElap2gv fv7N9KxxsZTEwyXP7oZi2rR9mW+nnfkIngl/nl7o/4b5gJEm8OmbqRz7e/m21a+O2SUb 2Ec8pNBkzUtGRWCbLWS9W54hShHEoqqmnajg46XnNx7NDtxi6wmcgzNaJuqWn+QT2MJi e5GYRyWTOhaZh6N6sC0VHV8l905DITcUxWak3Mh/4HBkSCDSbWTvtQOiBLi01aRt1T9s 5iZA== X-Gm-Message-State: AOAM532JGGZCoCUe5mHyhpQsuN+3h7vl+PgxwFYJrjnSqRWwbyXXXNKK 3w5NcHNDK+ktmQqBADtKIxP13xaH2LRZyw== X-Google-Smtp-Source: ABdhPJwoA5kLxH9Lt2zuX3bTD4YVsBbbF175Il2InPrigtR6yr7Tes3SySALdaiKOheyVncj7ys0xQ== X-Received: by 2002:a2e:5756:: with SMTP id r22mr3965044ljd.481.1610656965377; Thu, 14 Jan 2021 12:42:45 -0800 (PST) From: Andrew Melnychenko To: jasowang@redhat.com, mst@redhat.com Subject: [RFC PATCH v3 5/6] virtio-net: Added eBPF RSS to virtio-net. Date: Thu, 14 Jan 2021 23:16:11 +0200 Message-Id: <20210114211612.387052-6-andrew@daynix.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210114211612.387052-1-andrew@daynix.com> References: <20210114211612.387052-1-andrew@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2a00:1450:4864:20::22e; envelope-from=andrew@daynix.com; helo=mail-lj1-x22e.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: yan@daynix.com, yuri.benditovich@daynix.com, berrange@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Andrew When RSS is enabled the device tries to load the eBPF program to select RX virtqueue in the TUN. If eBPF can be loaded the RSS will function also with vhost (works with kernel 5.8 and later). Software RSS is used as a fallback with vhost=3Doff when eBPF can't be load= ed or when hash population requested by the guest. Signed-off-by: Yuri Benditovich Signed-off-by: Andrew Melnychenko --- hw/net/vhost_net.c | 2 + hw/net/virtio-net.c | 125 +++++++++++++++++++++++++++++++-- include/hw/virtio/virtio-net.h | 4 ++ net/vhost-vdpa.c | 2 + 4 files changed, 129 insertions(+), 4 deletions(-) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 24d555e764..16124f99c3 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -71,6 +71,8 @@ static const int user_feature_bits[] =3D { VIRTIO_NET_F_MTU, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_RING_PACKED, + VIRTIO_NET_F_RSS, + VIRTIO_NET_F_HASH_REPORT, =20 /* This bit implies RARP isn't sent by QEMU out of band */ VIRTIO_NET_F_GUEST_ANNOUNCE, diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 09ceb02c9d..37016fc73a 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -691,6 +691,19 @@ static void virtio_net_set_queues(VirtIONet *n) =20 static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue); =20 +static uint64_t fix_ebpf_vhost_features(uint64_t features) +{ + /* If vhost=3Don & CONFIG_EBPF doesn't set - disable RSS feature */ + uint64_t ret =3D features; +#ifndef CONFIG_EBPF + virtio_clear_feature(&ret, VIRTIO_NET_F_RSS); +#endif + /* for now, there is no solution for populating the hash from eBPF */ + virtio_clear_feature(&ret, VIRTIO_NET_F_HASH_REPORT); + + return ret; +} + static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t featu= res, Error **errp) { @@ -725,9 +738,9 @@ static uint64_t virtio_net_get_features(VirtIODevice *v= dev, uint64_t features, return features; } =20 - virtio_clear_feature(&features, VIRTIO_NET_F_RSS); - virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT); - features =3D vhost_net_get_features(get_vhost_net(nc->peer), features); + features =3D fix_ebpf_vhost_features( + vhost_net_get_features(get_vhost_net(nc->peer), features)); + vdev->backend_features =3D features; =20 if (n->mtu_bypass_backend && @@ -1151,12 +1164,79 @@ static int virtio_net_handle_announce(VirtIONet *n,= uint8_t cmd, } } =20 +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 =3D false; + + virtio_net_detach_epbf_rss(n); +} + +static bool virtio_net_attach_ebpf_to_backend(NICState *nic, int prog_fd) +{ + NetClientState *nc =3D qemu_get_peer(qemu_get_queue(nic), 0); + if (nc =3D=3D NULL || nc->info->set_steering_ebpf =3D=3D NULL) { + return false; + } + + return nc->info->set_steering_ebpf(nc, prog_fd); +} + +static void rss_data_to_rss_config(struct VirtioNetRssData *data, + struct EBPFRSSConfig *config) +{ + config->redirect =3D data->redirect; + config->populate_hash =3D data->populate_hash; + config->hash_types =3D data->hash_types; + config->indirections_len =3D data->indirections_len; + config->default_queue =3D data->default_queue; +} + +static bool virtio_net_attach_epbf_rss(VirtIONet *n) +{ + struct EBPFRSSConfig config =3D {}; + + if (!ebpf_rss_is_loaded(&n->ebpf_rss)) { + return false; + } + + 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; + } + + if (!virtio_net_attach_ebpf_to_backend(n->nic, n->ebpf_rss.program_fd)= ) { + return false; + } + + return true; +} + +static void virtio_net_detach_epbf_rss(VirtIONet *n) +{ + virtio_net_attach_ebpf_to_backend(n->nic, -1); +} + +static bool virtio_net_load_ebpf(VirtIONet *n) +{ + if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) { + /* backend does't support steering ebpf */ + return false; + } + + return ebpf_rss_load(&n->ebpf_rss); +} + +static void virtio_net_unload_ebpf(VirtIONet *n) +{ + virtio_net_attach_ebpf_to_backend(n->nic, -1); + ebpf_rss_unload(&n->ebpf_rss); } =20 static uint16_t virtio_net_handle_rss(VirtIONet *n, @@ -1271,6 +1351,25 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n, goto error; } n->rss_data.enabled =3D 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 =3D 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 =3D true; + } + trace_virtio_net_rss_enable(n->rss_data.hash_types, n->rss_data.indirections_len, temp.b); @@ -1656,7 +1755,7 @@ static ssize_t virtio_net_receive_rcu(NetClientState = *nc, const uint8_t *buf, return -1; } =20 - if (!no_rss && n->rss_data.enabled) { + if (!no_rss && n->rss_data.enabled && n->rss_data.enabled_software_rss= ) { int index =3D virtio_net_process_rss(nc, buf, size); if (index >=3D 0) { NetClientState *nc2 =3D qemu_get_subqueue(n->nic, index); @@ -2760,6 +2859,18 @@ static int virtio_net_post_load_device(void *opaque,= int version_id) } =20 if (n->rss_data.enabled) { + n->rss_data.enabled_software_rss =3D 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)) { + error_report("Can't post-load eBPF RSS for vhost"); + } else { + warn_report("Can't post-load eBPF RSS - fallback to so= ftware RSS"); + n->rss_data.enabled_software_rss =3D true; + } + } + } + trace_virtio_net_rss_enable(n->rss_data.hash_types, n->rss_data.indirections_len, sizeof(n->rss_data.key)); @@ -3336,6 +3447,8 @@ static void virtio_net_device_realize(DeviceState *de= v, Error **errp) n->qdev =3D dev; =20 net_rx_pkt_init(&n->rx_pkt, false); + + virtio_net_load_ebpf(n); } =20 static void virtio_net_device_unrealize(DeviceState *dev) @@ -3344,6 +3457,8 @@ static void virtio_net_device_unrealize(DeviceState *= dev) VirtIONet *n =3D VIRTIO_NET(dev); int i, max_queues; =20 + virtio_net_unload_ebpf(n); + /* This will stop vhost backend if appropriate. */ virtio_net_set_status(vdev, 0); =20 @@ -3386,6 +3501,8 @@ static void virtio_net_instance_init(Object *obj) device_add_bootindex_property(obj, &n->nic_conf.bootindex, "bootindex", "/ethernet-phy@0", DEVICE(n)); + + ebpf_rss_init(&n->ebpf_rss); } =20 static int virtio_net_pre_save(void *opaque) diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 7e96d193aa..824a69c23f 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -21,6 +21,8 @@ #include "qemu/option_int.h" #include "qom/object.h" =20 +#include "ebpf/ebpf_rss.h" + #define TYPE_VIRTIO_NET "virtio-net-device" OBJECT_DECLARE_SIMPLE_TYPE(VirtIONet, VIRTIO_NET) =20 @@ -130,6 +132,7 @@ typedef struct VirtioNetRscChain { =20 typedef struct VirtioNetRssData { bool enabled; + bool enabled_software_rss; bool redirect; bool populate_hash; uint32_t hash_types; @@ -209,6 +212,7 @@ struct VirtIONet { Notifier migration_state; VirtioNetRssData rss_data; struct NetRxPkt *rx_pkt; + struct EBPFRSSContext ebpf_rss; }; =20 void virtio_net_set_netclient_name(VirtIONet *n, const char *name, diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index fe659ec9e2..8b14215549 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -54,6 +54,8 @@ const int vdpa_feature_bits[] =3D { VIRTIO_NET_F_MTU, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_RING_PACKED, + VIRTIO_NET_F_RSS, + VIRTIO_NET_F_HASH_REPORT, VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_STATUS, VHOST_INVALID_FEATURE_BIT --=20 2.30.0