mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 iQEcBAABAgAGBQJgudWYAAoJEO8Ells5jWIR3nIH/1N7d60CHf986IzLdUVF/b8g ME/SiDB+SdnYgmEmWhNhxWpWeroyPbKqhU/eSqvPj8E8BvKj9Ze1laFdaxs/kwos N03ly0T/jlbm1yMg0Y986zxjh3HE4fpQooWW3ToA3TgycDUtkHMMd0qVtRaTWv0M KG3MbyHsp7MkR3S4wHBkE9yrVDCziBibZvkxhhz1VpEHjRjNDoNbevotE5Gr43+N 50D2TxRNVd6MjN7KGJOXQHc7t22OKb2/1fKTS1Pp+oGnDxHh63G6pGQ4LpC8wEjW 2h49tcAWHQ4SafkDqyapXgTACHs4k4TV/zUg8cUDFtkAArawHppwYHoAXvz8kd8= =m1ZO -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging # gpg: Signature made Fri 04 Jun 2021 08:26:16 BST # gpg: using RSA key EF04965B398D6211 # 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 * remotes/jasowang/tags/net-pull-request: MAINTAINERS: Added eBPF maintainers information. docs: Added eBPF documentation. virtio-net: Added eBPF RSS to virtio-net. ebpf: Added eBPF RSS loader. ebpf: Added eBPF RSS program. net: Added SetSteeringEBPF method for NetClientState. net/tap: Added TUNSETSTEERINGEBPF code. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1cbd2d9149
27 changed files with 1607 additions and 4 deletions
|
@ -45,6 +45,7 @@ static const int kernel_feature_bits[] = {
|
|||
VIRTIO_NET_F_MTU,
|
||||
VIRTIO_F_IOMMU_PLATFORM,
|
||||
VIRTIO_F_RING_PACKED,
|
||||
VIRTIO_NET_F_HASH_REPORT,
|
||||
VHOST_INVALID_FEATURE_BIT
|
||||
};
|
||||
|
||||
|
@ -71,6 +72,8 @@ static const int user_feature_bits[] = {
|
|||
VIRTIO_NET_F_MTU,
|
||||
VIRTIO_F_IOMMU_PLATFORM,
|
||||
VIRTIO_F_RING_PACKED,
|
||||
VIRTIO_NET_F_RSS,
|
||||
VIRTIO_NET_F_HASH_REPORT,
|
||||
|
||||
/* This bit implies RARP isn't sent by QEMU out of band */
|
||||
VIRTIO_NET_F_GUEST_ANNOUNCE,
|
||||
|
|
|
@ -737,8 +737,9 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
|
|||
return features;
|
||||
}
|
||||
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
|
||||
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;
|
||||
|
||||
|
@ -1163,12 +1164,79 @@ 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);
|
||||
if (nc == NULL || nc->info->set_steering_ebpf == 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 = data->redirect;
|
||||
config->populate_hash = data->populate_hash;
|
||||
config->hash_types = data->hash_types;
|
||||
config->indirections_len = data->indirections_len;
|
||||
config->default_queue = data->default_queue;
|
||||
}
|
||||
|
||||
static bool virtio_net_attach_epbf_rss(VirtIONet *n)
|
||||
{
|
||||
struct EBPFRSSConfig config = {};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static uint16_t virtio_net_handle_rss(VirtIONet *n,
|
||||
|
@ -1283,6 +1351,25 @@ 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);
|
||||
|
@ -1668,7 +1755,7 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!no_rss && n->rss_data.enabled) {
|
||||
if (!no_rss && n->rss_data.enabled && n->rss_data.enabled_software_rss) {
|
||||
int index = virtio_net_process_rss(nc, buf, size);
|
||||
if (index >= 0) {
|
||||
NetClientState *nc2 = qemu_get_subqueue(n->nic, index);
|
||||
|
@ -2772,6 +2859,19 @@ 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));
|
||||
|
@ -3352,6 +3452,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
|
|||
n->qdev = dev;
|
||||
|
||||
net_rx_pkt_init(&n->rx_pkt, false);
|
||||
|
||||
if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
|
||||
virtio_net_load_ebpf(n);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_net_device_unrealize(DeviceState *dev)
|
||||
|
@ -3360,6 +3464,10 @@ static void virtio_net_device_unrealize(DeviceState *dev)
|
|||
VirtIONet *n = VIRTIO_NET(dev);
|
||||
int i, max_queues;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -3403,6 +3511,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);
|
||||
}
|
||||
|
||||
static int virtio_net_pre_save(void *opaque)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue