Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ebpf: Added eBPF map update through mmap.
Changed eBPF map updates through mmaped array.
Mmaped arrays provide direct access to map data.
It should omit using bpf_map_update_elem() call,
which may require capabilities that are not present.

Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
  • Loading branch information
AndrewAtDaynix authored and jasowang committed Sep 8, 2023
1 parent 34b2166 commit 0f4bc6d
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 23 deletions.
117 changes: 94 additions & 23 deletions ebpf/ebpf_rss.c
Expand Up @@ -27,19 +27,83 @@ 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 +130,50 @@ 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)
{
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;
}

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 +183,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 +217,20 @@ 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;
}
5 changes: 5 additions & 0 deletions ebpf/ebpf_rss.h
Expand Up @@ -20,6 +20,11 @@ struct EBPFRSSContext {
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 Down

0 comments on commit 0f4bc6d

Please sign in to comment.