Skip to content

Commit

Permalink
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into…
Browse files Browse the repository at this point in the history
… staging

# -----BEGIN PGP SIGNATURE-----
# Version: GnuPG v1
#
# iQEcBAABAgAGBQJk+sEHAAoJEO8Ells5jWIRMjUH/i6Sv+19/kz2CFOsfNT6tK0O
# hcOo8Pn7WKvEvFgMM7+mZVYQTHj+78hXyen1XgvzZh7557vDAQNo9wwl0fmSRTR4
# qg/ocWg2K4zeTt/DChv3bTpJgOf31nIxffDfGt4QlMw6AZFJqAcr8JHuG7ezq259
# a5yy3b83HA7vexuz9p1UmFat4ps4yLcd/q7EGr0zqBkmUWPWg3fzJSRCTXG0p6GK
# +5TUzjZBzK1FuGBLAea8+ULJahSTM11fjCG11qcptOQ9lbFqEHTZYgwgTcOCDxFv
# hObNgRBHuqlK/rjw8d6m6oE+I4LMSXfbllgH4zuRNKm4YWhzAs6SXsLIo1+yJH0=
# =EXgN
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 08 Sep 2023 02:36:55 EDT
# gpg:                using RSA key EF04965B398D6211
# gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" [full]
# Primary key fingerprint: 215D 46F4 8246 689E C77F  3562 EF04 965B 398D 6211

* tag 'net-pull-request' of https://github.com/jasowang/qemu:
  ebpf: Updated eBPF program and skeleton.
  qmp: Added new command to retrieve eBPF blob.
  virtio-net: Added property to load eBPF RSS with fds.
  ebpf: Added eBPF initialization by fds.
  ebpf: Added eBPF map update through mmap.
  net: add initial support for AF_XDP network backend
  e1000e: rename e1000e_ba_state and e1000e_write_hdr_to_rx_buffers
  igb: packet-split descriptors support
  igb: add IPv6 extended headers traffic detection
  igb: RX payload guest writting refactoring
  igb: RX descriptors guest writting refactoring
  igb: rename E1000E_RingInfo_st
  igb: remove TCP ACK detection
  virtio-net: Add support for USO features
  virtio-net: Add USO flags to vhost support.
  tap: Add check for USO features
  tap: Add USO support to tap device.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Sep 8, 2023
2 parents 759a86b + 049cfda commit 82e181a
Show file tree
Hide file tree
Showing 44 changed files with 2,518 additions and 1,025 deletions.
4 changes: 4 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,10 @@ W: http://info.iet.unipi.it/~luigi/netmap/
S: Maintained
F: net/netmap.c

AF_XDP network backend
R: Ilya Maximets <i.maximets@ovn.org>
F: net/af-xdp.c

Host Memory Backends
M: David Hildenbrand <david@redhat.com>
M: Igor Mammedov <imammedo@redhat.com>
Expand Down
70 changes: 70 additions & 0 deletions ebpf/ebpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* QEMU eBPF binary declaration routine.
*
* Developed by Daynix Computing LTD (http://www.daynix.com)
*
* Authors:
* Andrew Melnychenko <andrew@daynix.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/

#include "qemu/osdep.h"
#include "qemu/queue.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-ebpf.h"
#include "ebpf/ebpf.h"

struct ElfBinaryDataEntry {
int id;
const void *data;
size_t datalen;

QSLIST_ENTRY(ElfBinaryDataEntry) node;
};

static QSLIST_HEAD(, ElfBinaryDataEntry) ebpf_elf_obj_list =
QSLIST_HEAD_INITIALIZER();

void ebpf_register_binary_data(int id, const void *data, size_t datalen)
{
struct ElfBinaryDataEntry *dataentry = NULL;

dataentry = g_new0(struct ElfBinaryDataEntry, 1);
dataentry->data = data;
dataentry->datalen = datalen;
dataentry->id = id;

QSLIST_INSERT_HEAD(&ebpf_elf_obj_list, dataentry, node);
}

const void *ebpf_find_binary_by_id(int id, size_t *sz, Error **errp)
{
struct ElfBinaryDataEntry *it = NULL;
QSLIST_FOREACH(it, &ebpf_elf_obj_list, node) {
if (id == it->id) {
*sz = it->datalen;
return it->data;
}
}

error_setg(errp, "can't find eBPF object with id: %d", id);

return NULL;
}

EbpfObject *qmp_request_ebpf(EbpfProgramID id, Error **errp)
{
EbpfObject *ret = NULL;
size_t size = 0;
const void *data = ebpf_find_binary_by_id(id, &size, errp);
if (!data) {
return NULL;
}

ret = g_new0(EbpfObject, 1);
ret->object = g_base64_encode(data, size);

return ret;
}
31 changes: 31 additions & 0 deletions ebpf/ebpf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* QEMU eBPF binary declaration routine.
*
* Developed by Daynix Computing LTD (http://www.daynix.com)
*
* Authors:
* Andrew Melnychenko <andrew@daynix.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/

#ifndef EBPF_H
#define EBPF_H

struct Error;

void ebpf_register_binary_data(int id, const void *data,
size_t datalen);
const void *ebpf_find_binary_by_id(int id, size_t *sz,
struct Error **errp);

#define ebpf_binary_init(id, fn) \
static void __attribute__((constructor)) ebpf_binary_init_ ## fn(void) \
{ \
size_t datalen = 0; \
const void *data = fn(&datalen); \
ebpf_register_binary_data(id, data, datalen); \
}

#endif /* EBPF_H */
6 changes: 6 additions & 0 deletions ebpf/ebpf_rss-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
return false;
}

bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
int config_fd, int toeplitz_fd, int table_fd)
{
return false;
}

bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
uint16_t *indirections_table, uint8_t *toeplitz_key)
{
Expand Down
150 changes: 127 additions & 23 deletions ebpf/ebpf_rss.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/qapi-types-misc.h"
#include "qapi/qapi-commands-ebpf.h"

#include <bpf/libbpf.h>
#include <bpf/bpf.h>
Expand All @@ -21,25 +23,91 @@

#include "ebpf/ebpf_rss.h"
#include "ebpf/rss.bpf.skeleton.h"
#include "ebpf/ebpf.h"

#include "trace.h"

void ebpf_rss_init(struct EBPFRSSContext *ctx)
{
if (ctx != NULL) {
ctx->obj = NULL;
ctx->program_fd = -1;
ctx->map_configuration = -1;
ctx->map_toeplitz_key = -1;
ctx->map_indirections_table = -1;

ctx->mmap_configuration = NULL;
ctx->mmap_toeplitz_key = NULL;
ctx->mmap_indirections_table = NULL;
}
}

bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx)
{
return ctx != NULL && ctx->obj != NULL;
return ctx != NULL && (ctx->obj != NULL || ctx->program_fd != -1);
}

static bool ebpf_rss_mmap(struct EBPFRSSContext *ctx)
{
if (!ebpf_rss_is_loaded(ctx)) {
return false;
}

ctx->mmap_configuration = mmap(NULL, qemu_real_host_page_size(),
PROT_READ | PROT_WRITE, MAP_SHARED,
ctx->map_configuration, 0);
if (ctx->mmap_configuration == MAP_FAILED) {
trace_ebpf_error("eBPF RSS", "can not mmap eBPF configuration array");
return false;
}
ctx->mmap_toeplitz_key = mmap(NULL, qemu_real_host_page_size(),
PROT_READ | PROT_WRITE, MAP_SHARED,
ctx->map_toeplitz_key, 0);
if (ctx->mmap_toeplitz_key == MAP_FAILED) {
trace_ebpf_error("eBPF RSS", "can not mmap eBPF toeplitz key");
goto toeplitz_fail;
}
ctx->mmap_indirections_table = mmap(NULL, qemu_real_host_page_size(),
PROT_READ | PROT_WRITE, MAP_SHARED,
ctx->map_indirections_table, 0);
if (ctx->mmap_indirections_table == MAP_FAILED) {
trace_ebpf_error("eBPF RSS", "can not mmap eBPF indirection table");
goto indirection_fail;
}

return true;

indirection_fail:
munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
toeplitz_fail:
munmap(ctx->mmap_configuration, qemu_real_host_page_size());

ctx->mmap_configuration = NULL;
ctx->mmap_toeplitz_key = NULL;
ctx->mmap_indirections_table = NULL;
return false;
}

static void ebpf_rss_munmap(struct EBPFRSSContext *ctx)
{
if (!ebpf_rss_is_loaded(ctx)) {
return;
}

munmap(ctx->mmap_indirections_table, qemu_real_host_page_size());
munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
munmap(ctx->mmap_configuration, qemu_real_host_page_size());

ctx->mmap_configuration = NULL;
ctx->mmap_toeplitz_key = NULL;
ctx->mmap_indirections_table = NULL;
}

bool ebpf_rss_load(struct EBPFRSSContext *ctx)
{
struct rss_bpf *rss_bpf_ctx;

if (ctx == NULL) {
if (ctx == NULL || ebpf_rss_is_loaded(ctx)) {
return false;
}

Expand All @@ -66,54 +134,77 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
ctx->map_toeplitz_key = bpf_map__fd(
rss_bpf_ctx->maps.tap_rss_map_toeplitz_key);

if (!ebpf_rss_mmap(ctx)) {
goto error;
}

return true;
error:
rss_bpf__destroy(rss_bpf_ctx);
ctx->obj = NULL;
ctx->program_fd = -1;
ctx->map_configuration = -1;
ctx->map_toeplitz_key = -1;
ctx->map_indirections_table = -1;

return false;
}

static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
struct EBPFRSSConfig *config)
bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
int config_fd, int toeplitz_fd, int table_fd)
{
uint32_t map_key = 0;
if (ctx == NULL || ebpf_rss_is_loaded(ctx)) {
return false;
}

if (!ebpf_rss_is_loaded(ctx)) {
if (program_fd < 0 || config_fd < 0 || toeplitz_fd < 0 || table_fd < 0) {
return false;
}

ctx->program_fd = program_fd;
ctx->map_configuration = config_fd;
ctx->map_toeplitz_key = toeplitz_fd;
ctx->map_indirections_table = table_fd;

if (!ebpf_rss_mmap(ctx)) {
ctx->program_fd = -1;
ctx->map_configuration = -1;
ctx->map_toeplitz_key = -1;
ctx->map_indirections_table = -1;
return false;
}
if (bpf_map_update_elem(ctx->map_configuration,
&map_key, config, 0) < 0) {

return true;
}

static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
struct EBPFRSSConfig *config)
{
if (!ebpf_rss_is_loaded(ctx)) {
return false;
}

memcpy(ctx->mmap_configuration, config, sizeof(*config));
return true;
}

static bool 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;
}

for (; i < len; ++i) {
if (bpf_map_update_elem(ctx->map_indirections_table, &i,
indirections_table + i, 0) < 0) {
return false;
}
}
memcpy(ctx->mmap_indirections_table, indirections_table,
sizeof(*indirections_table) * len);
return true;
}

static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
uint8_t *toeplitz_key)
{
uint32_t map_key = 0;

/* prepare toeplitz key */
uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};

Expand All @@ -123,10 +214,7 @@ static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
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;
}
memcpy(ctx->mmap_toeplitz_key, toe, VIRTIO_NET_RSS_MAX_KEY_SIZE);
return true;
}

Expand Down Expand Up @@ -160,6 +248,22 @@ void ebpf_rss_unload(struct EBPFRSSContext *ctx)
return;
}

rss_bpf__destroy(ctx->obj);
ebpf_rss_munmap(ctx);

if (ctx->obj) {
rss_bpf__destroy(ctx->obj);
} else {
close(ctx->program_fd);
close(ctx->map_configuration);
close(ctx->map_toeplitz_key);
close(ctx->map_indirections_table);
}

ctx->obj = NULL;
ctx->program_fd = -1;
ctx->map_configuration = -1;
ctx->map_toeplitz_key = -1;
ctx->map_indirections_table = -1;
}

ebpf_binary_init(EBPF_PROGRAMID_RSS, rss_bpf__elf_bytes)
10 changes: 10 additions & 0 deletions ebpf/ebpf_rss.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@
#ifndef QEMU_EBPF_RSS_H
#define QEMU_EBPF_RSS_H

#define EBPF_RSS_MAX_FDS 4

struct EBPFRSSContext {
void *obj;
int program_fd;
int map_configuration;
int map_toeplitz_key;
int map_indirections_table;

/* mapped eBPF maps for direct access to omit bpf_map_update_elem() */
void *mmap_configuration;
void *mmap_toeplitz_key;
void *mmap_indirections_table;
};

struct EBPFRSSConfig {
Expand All @@ -36,6 +43,9 @@ bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx);

bool ebpf_rss_load(struct EBPFRSSContext *ctx);

bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
int config_fd, int toeplitz_fd, int table_fd);

bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
uint16_t *indirections_table, uint8_t *toeplitz_key);

Expand Down
2 changes: 1 addition & 1 deletion ebpf/meson.build
Original file line number Diff line number Diff line change
@@ -1 +1 @@
system_ss.add(when: libbpf, if_true: files('ebpf_rss.c'), if_false: files('ebpf_rss-stub.c'))
common_ss.add(when: libbpf, if_true: files('ebpf.c', 'ebpf_rss.c'), if_false: files('ebpf_rss-stub.c'))

0 comments on commit 82e181a

Please sign in to comment.