Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3migration for review #1

Open
wants to merge 8 commits into
base: temp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ vhost_vsock="$default_feature"
vhost_user="no"
vhost_user_blk_server="auto"
vhost_user_fs="$default_feature"
bpf=""
kvm="auto"
hax="auto"
hvf="auto"
Expand Down Expand Up @@ -1236,6 +1237,10 @@ for opt do
;;
--enable-membarrier) membarrier="yes"
;;
--disable-bpf) bpf="no"
;;
--enable-bpf) bpf="yes"
;;
--disable-blobs) blobs="false"
;;
--with-pkgversion=*) pkgversion="$optarg"
Expand Down Expand Up @@ -1845,6 +1850,7 @@ disabled with --disable-FEATURE, default is enabled if available
vhost-user vhost-user backend support
vhost-user-blk-server vhost-user-blk server support
vhost-vdpa vhost-vdpa kernel backend support
bpf BPF kernel support
spice spice
rbd rados block device (rbd)
libiscsi iscsi support
Expand Down Expand Up @@ -5057,6 +5063,30 @@ else
membarrier=no
fi

##########################################
# check for usable bpf system call
if test "$bpf" = ""; then
have_bpf=no
if test "$linux" = "yes" -a "$bigendian" != "yes"; then
cat > $TMPC << EOF
#include <stdlib.h>
#include <bpf/libbpf.h>
int main(void) {
struct bpf_object *obj = NULL;
bpf_object__load(obj);
exit(0);
}
EOF
if compile_prog "" "-lbpf" ; then
have_bpf=yes
bpf=yes
fi
fi
if test "$have_bpf" = "no"; then
feature_not_found "bpf" "the libbpf is not available"
fi
fi

##########################################
# check if rtnetlink.h exists and is useful
have_rtnetlink=no
Expand Down Expand Up @@ -5905,6 +5935,9 @@ fi
if test "$membarrier" = "yes" ; then
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
fi
if test "$bpf" = "yes" -a "$bigendian" != "yes" -a "$linux" = "yes" ; then
echo "CONFIG_EBPF=y" >> $config_host_mak
fi
if test "$signalfd" = "yes" ; then
echo "CONFIG_SIGNALFD=y" >> $config_host_mak
fi
Expand Down
40 changes: 40 additions & 0 deletions ebpf/ebpf_rss-stub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* eBPF RSS stub file
*
* Developed by Daynix Computing LTD (http://www.daynix.com)
*
* Authors:
* Yuri Benditovich <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/

#include "qemu/osdep.h"
#include "ebpf/ebpf_rss.h"

void ebpf_rss_init(struct EBPFRSSContext *ctx)
{

}

bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx)
{
return false;
}

bool ebpf_rss_load(struct EBPFRSSContext *ctx)
{
return false;
}

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

void ebpf_rss_unload(struct EBPFRSSContext *ctx)
{

}
165 changes: 165 additions & 0 deletions ebpf/ebpf_rss.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* eBPF RSS loader
*
* Developed by Daynix Computing LTD (http://www.daynix.com)
*
* Authors:
* Andrew Melnychenko <[email protected]>
* Yuri Benditovich <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/

#include "qemu/osdep.h"
#include "qemu/error-report.h"

#include <bpf/libbpf.h>
#include <bpf/bpf.h>

#include "hw/virtio/virtio-net.h" /* VIRTIO_NET_RSS_MAX_TABLE_LEN */

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

void ebpf_rss_init(struct EBPFRSSContext *ctx)
{
if (ctx != NULL) {
ctx->obj = NULL;
}
}

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

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

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

rss_bpf_ctx = rss_bpf__open();
if (rss_bpf_ctx == NULL) {
trace_ebpf_error("eBPF RSS", "can not open eBPF RSS object");
goto l_issue;
}

bpf_program__set_socket_filter(rss_bpf_ctx->progs.tun_rss_steering_prog);

if (rss_bpf__load(rss_bpf_ctx)) {
trace_ebpf_error("eBPF RSS", "can not load RSS program");
goto l_issue;
}

ctx->obj = rss_bpf_ctx;
ctx->program_fd = bpf_program__fd(
rss_bpf_ctx->progs.tun_rss_steering_prog);
ctx->map_configuration = bpf_map__fd(
rss_bpf_ctx->maps.tap_rss_map_configurations);
ctx->map_indirections_table = bpf_map__fd(
rss_bpf_ctx->maps.tap_rss_map_indirection_table);
ctx->map_toeplitz_key = bpf_map__fd(
rss_bpf_ctx->maps.tap_rss_map_toeplitz_key);

return true;
l_issue:
rss_bpf__destroy(rss_bpf_ctx);
ctx->obj = NULL;

return false;
}

static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
struct EBPFRSSConfig *config)
{
uint32_t map_key = 0;

if (!ebpf_rss_is_loaded(ctx)) {
return false;
}
if (bpf_map_update_elem(ctx->map_configuration,
&map_key, config, 0) < 0) {
return false;
}
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;
}
}
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] = {};

if (!ebpf_rss_is_loaded(ctx) || toeplitz_key == NULL) {
return false;
}
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;
}
return true;
}

bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
uint16_t *indirections_table, uint8_t *toeplitz_key)
{
if (!ebpf_rss_is_loaded(ctx) || config == NULL ||
indirections_table == NULL || toeplitz_key == NULL) {
return false;
}

if (!ebpf_rss_set_config(ctx, config)) {
return false;
}

if (!ebpf_rss_set_indirections_table(ctx, indirections_table,
config->indirections_len)) {
return false;
}

if (!ebpf_rss_set_toepliz_key(ctx, toeplitz_key)) {
return false;
}

return true;
}

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

rss_bpf__destroy(ctx->obj);
ctx->obj = NULL;
}
44 changes: 44 additions & 0 deletions ebpf/ebpf_rss.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* eBPF RSS header
*
* Developed by Daynix Computing LTD (http://www.daynix.com)
*
* Authors:
* Andrew Melnychenko <[email protected]>
* Yuri Benditovich <[email protected]>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/

#ifndef QEMU_EBPF_RSS_H
#define QEMU_EBPF_RSS_H

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

struct EBPFRSSConfig {
uint8_t redirect;
uint8_t populate_hash;
uint32_t hash_types;
uint16_t indirections_len;
uint16_t default_queue;
};

void ebpf_rss_init(struct EBPFRSSContext *ctx);

bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx);

bool ebpf_rss_load(struct EBPFRSSContext *ctx);

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

void ebpf_rss_unload(struct EBPFRSSContext *ctx);

#endif /* QEMU_EBPF_RSS_H */
1 change: 1 addition & 0 deletions ebpf/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
common_ss.add(when: 'CONFIG_EBPF', if_true: files('ebpf_rss.c'), if_false: files('ebpf_rss-stub.c'))
Loading