From: "Emil Tsalapatis" <emil@etsalapatis.com>
To: "Mykyta Yatsenko" <mykyta.yatsenko5@gmail.com>,
<bpf@vger.kernel.org>, <ast@kernel.org>, <andrii@kernel.org>,
<daniel@iogearbox.net>, <kafai@meta.com>, <kernel-team@meta.com>,
<eddyz87@gmail.com>, <memxor@gmail.com>,
<herbert@gondor.apana.org.au>
Cc: "Mykyta Yatsenko" <yatsenko@meta.com>
Subject: Re: [PATCH RFC bpf-next v2 05/18] bpf: Implement get_next_key and free_internal_structs for resizable hashtab
Date: Mon, 13 Apr 2026 18:44:52 -0400 [thread overview]
Message-ID: <DHSE3ICYF886.1JAWWOKCDODDF@etsalapatis.com> (raw)
In-Reply-To: <20260408-rhash-v2-5-3b3675da1f6e@meta.com>
On Wed Apr 8, 2026 at 11:10 AM EDT, Mykyta Yatsenko wrote:
> From: Mykyta Yatsenko <yatsenko@meta.com>
>
> Implement rhtab_map_get_next_key() and rhtab_map_free_internal_structs()
> of the BPF resizable hashtable. Both are only called from syscall, so
> it's safe to use rhashtable walk API that uses spinlocks internally.
>
> Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
> ---
> kernel/bpf/hashtab.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 77 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
> index ea7314cc3703..7eee450a321e 100644
> --- a/kernel/bpf/hashtab.c
> +++ b/kernel/bpf/hashtab.c
> @@ -2921,13 +2921,89 @@ static int rhtab_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf)
> return insn - insn_buf;
> }
>
> +/* Helper to get next element, handling -EAGAIN during resize */
> +static struct rhtab_elem *rhtab_iter_next(struct rhashtable_iter *iter)
> +{
> + struct rhtab_elem *elem;
> +
> + while ((elem = rhashtable_walk_next(iter))) {
> + if (IS_ERR(elem)) {
> + if (PTR_ERR(elem) == -EAGAIN)
> + continue;
> + return NULL;
> + }
> + return elem;
> + }
> +
> + return NULL;
> +}
> +
> static void rhtab_map_free_internal_structs(struct bpf_map *map)
> {
> + struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
> + struct rhashtable_iter iter;
> + struct rhtab_elem *elem;
> +
> + if (!bpf_map_has_internal_structs(map))
> + return;
> +
> + /*
> + * An element can be processed twice if rhashtable resized concurrently.
> + * Special structs freeing handles duplicate cancel_and_free.
> + */
> + rhashtable_walk_enter(&rhtab->ht, &iter);
> + rhashtable_walk_start(&iter);
> +
> + for (elem = rhtab_iter_next(&iter); elem; elem = rhtab_iter_next(&iter))
> + bpf_map_free_internal_structs(map, rhtab_elem_value(elem, map->key_size));
> +
> + rhashtable_walk_stop(&iter);
> + rhashtable_walk_exit(&iter);
> }
>
> static int rhtab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
> {
> - return -EOPNOTSUPP;
> + struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
> + struct rhashtable_iter iter;
> + struct rhtab_elem *elem;
> + bool key_found;
> + int ret = -ENOENT;
> +
> + /*
> + * Hold RCU across enter_from + walk_start to prevent the
> + * element cached by enter_from from being freed before
> + * walk_start re-acquires RCU.
> + */
> + guard(rcu)();
> + rhashtable_walk_enter_from(&rhtab->ht, &iter, key, rhtab->params);
> + key_found = key && iter.p;
> + rhashtable_walk_start(&iter);
> +
> + elem = rhtab_iter_next(&iter);
> + if (elem) {
> + memcpy(next_key, elem->data, map->key_size);
> + ret = 0;
> + }
> +
> + rhashtable_walk_stop(&iter);
> + rhashtable_walk_exit(&iter);
> +
> + if (ret == 0 || key_found)
> + return ret;
> +
> + /* Key was not found restart from the beginning */
> + rhashtable_walk_enter(&rhtab->ht, &iter);
> + rhashtable_walk_start(&iter);
> +
> + elem = rhtab_iter_next(&iter);
> + if (elem) {
> + memcpy(next_key, elem->data, map->key_size);
> + ret = 0;
> + }
> +
> + rhashtable_walk_stop(&iter);
> + rhashtable_walk_exit(&iter);
Nit: The two attempts are partly identical, can you try to
roll them together and use a goto to retry? Or do you think
this will be too messy?
Otherwise:
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
> + return ret;
> }
>
> static void rhtab_map_seq_show_elem(struct bpf_map *map, void *key, struct seq_file *m)
next prev parent reply other threads:[~2026-04-13 22:44 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-08 15:10 [PATCH RFC bpf-next v2 00/18] bpf: Introduce resizable hash map Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 01/18] bpf: Register rhash map Mykyta Yatsenko
2026-04-10 22:31 ` Emil Tsalapatis
2026-04-13 8:10 ` Mykyta Yatsenko
2026-04-14 17:50 ` Emil Tsalapatis
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 02/18] bpf: Add resizable hashtab skeleton Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 03/18] bpf: Implement lookup, delete, update for resizable hashtab Mykyta Yatsenko
2026-04-12 23:10 ` Alexei Starovoitov
2026-04-13 10:52 ` Mykyta Yatsenko
2026-04-13 16:24 ` Alexei Starovoitov
2026-04-13 16:27 ` Daniel Borkmann
2026-04-13 19:43 ` Mykyta Yatsenko
2026-04-13 20:37 ` Emil Tsalapatis
2026-04-14 8:34 ` Mykyta Yatsenko
2026-04-14 10:25 ` Leon Hwang
2026-04-14 10:28 ` Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 04/18] rhashtable: Add rhashtable_walk_enter_from() Mykyta Yatsenko
2026-04-12 23:13 ` Alexei Starovoitov
2026-04-13 12:22 ` Mykyta Yatsenko
2026-04-13 22:22 ` Emil Tsalapatis
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 05/18] bpf: Implement get_next_key and free_internal_structs for resizable hashtab Mykyta Yatsenko
2026-04-13 22:44 ` Emil Tsalapatis [this message]
2026-04-14 8:11 ` Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 06/18] bpf: Implement bpf_each_rhash_elem() using walk API Mykyta Yatsenko
2026-04-13 23:02 ` Emil Tsalapatis
2026-04-24 15:16 ` Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 07/18] bpf: Implement batch ops for resizable hashtab Mykyta Yatsenko
2026-04-13 23:25 ` Emil Tsalapatis
2026-04-14 8:08 ` Mykyta Yatsenko
2026-04-14 17:47 ` Emil Tsalapatis
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 08/18] bpf: Implement iterator APIs " Mykyta Yatsenko
2026-04-14 17:49 ` Emil Tsalapatis
2026-04-15 11:15 ` Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 09/18] bpf: Implement alloc and free " Mykyta Yatsenko
2026-04-12 23:15 ` Alexei Starovoitov
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 10/18] bpf: Allow timers, workqueues and task_work in " Mykyta Yatsenko
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 11/18] libbpf: Support resizable hashtable Mykyta Yatsenko
2026-04-14 17:46 ` Emil Tsalapatis
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 12/18] selftests/bpf: Add basic tests for resizable hash map Mykyta Yatsenko
2026-04-12 23:16 ` Alexei Starovoitov
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 13/18] selftests/bpf: Support resizable hashtab in test_maps Mykyta Yatsenko
2026-04-12 23:17 ` Alexei Starovoitov
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 14/18] selftests/bpf: Resizable hashtab BPF_F_LOCK tests Mykyta Yatsenko
2026-04-12 23:18 ` Alexei Starovoitov
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 15/18] selftests/bpf: Add stress tests for resizable hash get_next_key Mykyta Yatsenko
2026-04-12 23:19 ` Alexei Starovoitov
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 16/18] selftests/bpf: Add BPF iterator tests for resizable hash map Mykyta Yatsenko
2026-04-12 23:20 ` Alexei Starovoitov
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 17/18] bpftool: Add rhash map documentation Mykyta Yatsenko
2026-04-14 17:51 ` Emil Tsalapatis
2026-04-08 15:10 ` [PATCH RFC bpf-next v2 18/18] selftests/bpf: Add resizable hashmap to benchmarks Mykyta Yatsenko
2026-04-12 23:25 ` Alexei Starovoitov
2026-04-12 23:11 ` [PATCH RFC bpf-next v2 00/18] bpf: Introduce resizable hash map Alexei Starovoitov
2026-04-13 8:28 ` Mykyta Yatsenko
2026-04-15 3:27 ` Herbert Xu
2026-04-15 5:13 ` Alexei Starovoitov
2026-04-16 5:18 ` Herbert Xu
2026-04-16 14:11 ` Alexei Starovoitov
2026-04-16 15:10 ` Mykyta Yatsenko
2026-04-16 15:36 ` Alexei Starovoitov
2026-04-16 16:30 ` Mykyta Yatsenko
2026-04-17 6:54 ` Herbert Xu
2026-04-17 15:16 ` Mykyta Yatsenko
2026-04-18 0:43 ` Herbert Xu
2026-04-20 11:45 ` Mykyta Yatsenko
2026-04-20 15:41 ` Alexei Starovoitov
2026-04-20 15:50 ` Mykyta Yatsenko
2026-04-20 16:06 ` Alexei Starovoitov
2026-04-20 16:37 ` Mykyta Yatsenko
2026-04-20 18:00 ` Alexei Starovoitov
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=DHSE3ICYF886.1JAWWOKCDODDF@etsalapatis.com \
--to=emil@etsalapatis.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=herbert@gondor.apana.org.au \
--cc=kafai@meta.com \
--cc=kernel-team@meta.com \
--cc=memxor@gmail.com \
--cc=mykyta.yatsenko5@gmail.com \
--cc=yatsenko@meta.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.