From: Jason Wang <jasowang@redhat.com>
To: Andrew Melnychenko <andrew@daynix.com>
Cc: mst@redhat.com, armbru@redhat.com, eblake@redhat.com,
berrange@redhat.com, qemu-devel@nongnu.org,
yuri.benditovich@daynix.com, yan@daynix.com
Subject: Re: [PATCH v5 1/5] ebpf: Added eBPF map update through mmap.
Date: Tue, 8 Aug 2023 10:39:14 +0800 [thread overview]
Message-ID: <CACGkMEshvbR3kK+NWqHqDZBkDNLHkWPtxTPE-hVhtaSzAeBvcA@mail.gmail.com> (raw)
In-Reply-To: <20230802204125.33688-2-andrew@daynix.com>
On Thu, Aug 3, 2023 at 5:01 AM Andrew Melnychenko <andrew@daynix.com> wrote:
>
> 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>
> ---
> ebpf/ebpf_rss.c | 117 ++++++++++++++++++++++++++++++++++++++----------
> ebpf/ebpf_rss.h | 5 +++
> 2 files changed, 99 insertions(+), 23 deletions(-)
>
> diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
> index cee658c158b..247f5eee1b6 100644
> --- a/ebpf/ebpf_rss.c
> +++ b/ebpf/ebpf_rss.c
> @@ -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;
> }
>
> @@ -66,10 +130,18 @@ 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;
> }
> @@ -77,15 +149,11 @@ error:
> 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;
> }
>
> @@ -93,27 +161,19 @@ 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);
As discussed, should we stick the compatibility on the host without
bpf mmap support?
If we don't, we need at least probe BPF mmap and disable ebpf rss? If
yes, we should track if the map is mmaped and switch between memcpy
and syscall.
Thanks
> 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] = {};
>
> @@ -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;
> }
>
> @@ -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;
> }
> diff --git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
> index bf3f2572c7c..ab08a7266d0 100644
> --- a/ebpf/ebpf_rss.h
> +++ b/ebpf/ebpf_rss.h
> @@ -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 {
> --
> 2.41.0
>
next prev parent reply other threads:[~2023-08-08 2:40 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-02 20:41 [PATCH v5 0/5] eBPF RSS through QMP support Andrew Melnychenko
2023-08-02 20:41 ` [PATCH v5 1/5] ebpf: Added eBPF map update through mmap Andrew Melnychenko
2023-08-08 2:39 ` Jason Wang [this message]
2023-08-08 23:15 ` Andrew Melnichenko
2023-08-09 2:21 ` Jason Wang
2023-08-14 8:36 ` Andrew Melnichenko
2023-08-16 1:16 ` Jason Wang
2023-08-18 2:07 ` Andrew Melnichenko
2023-08-21 3:57 ` Jason Wang
2023-08-02 20:41 ` [PATCH v5 2/5] ebpf: Added eBPF initialization by fds Andrew Melnychenko
2023-08-02 20:41 ` [PATCH v5 3/5] virtio-net: Added property to load eBPF RSS with fds Andrew Melnychenko
2023-08-02 20:41 ` [PATCH v5 4/5] qmp: Added new command to retrieve eBPF blob Andrew Melnychenko
2023-08-03 14:16 ` Daniel P. Berrangé
2023-08-05 7:34 ` Markus Armbruster
2023-08-08 17:43 ` Andrew Melnichenko
2023-08-21 17:15 ` Markus Armbruster
2023-08-02 20:41 ` [PATCH v5 5/5] ebpf: Updated eBPF program and skeleton Andrew Melnychenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CACGkMEshvbR3kK+NWqHqDZBkDNLHkWPtxTPE-hVhtaSzAeBvcA@mail.gmail.com \
--to=jasowang@redhat.com \
--cc=andrew@daynix.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=eblake@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=yan@daynix.com \
--cc=yuri.benditovich@daynix.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).