Re: [PATCH RFC bpf-next v2 06/18] bpf: Implement bpf_each_rhash_elem() using walk API

Emil Tsalapatis
2026-04-13T23:02:46Z

On Wed Apr 8, 2026 at 11:10 AM EDT, Mykyta Yatsenko wrote:
> From: Mykyta Yatsenko <yatsenko@meta.com>
>
> rhashtable walk API takes spin_lock(&ht->lock) in start/stop,
> making it unsafe in NMI and hard IRQ contexts. Guard with
> !in_task() rather than open-coding raw RCU
> iteration that would need to handle resize races manually.
>
> Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
> ---
> kernel/bpf/hashtab.c | 35 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
> index 7eee450a321e..e79c194e2779 100644
> --- a/kernel/bpf/hashtab.c
> +++ b/kernel/bpf/hashtab.c
> @@ -3013,7 +3013,40 @@ static void rhtab_map_seq_show_elem(struct bpf_map *map, void *key, struct seq_f
> static long bpf_each_rhash_elem(struct bpf_map *map, bpf_callback_t callback_fn,
> void *callback_ctx, u64 flags)
> {
> - return -EOPNOTSUPP;
> + struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
> + struct rhashtable_iter iter;
> + struct rhtab_elem *elem;
> + int num_elems = 0;
> + u64 ret = 0;
> +
> + if (flags != 0)
> + return -EINVAL;
> +
> + /*
> + * The rhashtable walk API uses spin_lock(&ht->lock) in rhashtable_walk_start/stop,
> + * which is not safe in NMI or soft/hard IRQ context.
> + */
> + if (!in_task())
> + return -EOPNOTSUPP;

Use in_nmi()/in_hardirq()/in_softirq() instead?

> +
> + rhashtable_walk_enter(&rhtab->ht, &iter);
> + rhashtable_walk_start(&iter);
> +
> + for (elem = rhtab_iter_next(&iter); elem;
> + elem = rhtab_iter_next(&iter)) {
> + num_elems++;
> + ret = callback_fn((u64)(long)map,
> + (u64)(long)elem->data,
> + (u64)(long)rhtab_elem_value(elem, map->key_size),
> + (u64)(long)callback_ctx, 0);

AFAICT this callback is impossible to be sleepable which is why we're
able to call it under RCU, can we note this here in a comment?

> + if (ret)
> + break;
> + }
> +
> + rhashtable_walk_stop(&iter);
> + rhashtable_walk_exit(&iter);
> +
> + return num_elems;
> }
>
> static u64 rhtab_map_mem_usage(const struct bpf_map *map)