All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: 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,
	Mykyta Yatsenko <yatsenko@meta.com>
Subject: Re: [PATCH bpf-next v3 02/10] rhashtable: Add rhashtable_walk_enter_from()
Date: Fri, 8 May 2026 15:22:14 +0100	[thread overview]
Message-ID: <bce63f2c-be86-4c6c-b8a9-6bea3de692ea@gmail.com> (raw)
In-Reply-To: <afxMsrMYRDHZMIa_@gondor.apana.org.au>

On 5/7/26 9:26 AM, Herbert Xu wrote:
> On Tue, May 05, 2026 at 05:57:41PM +0100, Mykyta Yatsenko wrote:
>>
>> We brainstormed with Alexei on how to integrate rhashtable better,
>> as a BPF map, we have the next proposal:
>>
>> Introduce rhashtable_next_key() API
>> ```
>> static inline struct rhash_head *rhashtable_next_key(
>> 	struct rhashtable *ht, const void *prev_key,
>> 	const struct rhashtable_params params);
>> ```
>>
>> It returns the next element, by finding prev_key in the tbl chain
>> and returning the next element in whatever tbl the prev one is.
>> This way we keep rhashtable API tight, less surface, not exposing unnecessary
>> details, although, this new API will have the same issues with full
>> iteration support (which we fine to deal with on userspace side).
>> Appreciate if you share your opinion on this.
> 
> Can you please show me how this gets used? Basically send me the
> patch 03 from your v3 series with this new interface.
> 
> Thanks,

Below is the example of the get_next_key() from BPF using rhashtable_next_key(),
I also included an implementation from rhashtable.

hashtab.c:
==========

static int rhtab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
	__must_hold_shared(RCU)
{
	struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
	struct rhtab_elem *elem;

	elem = rhashtable_next_key(&rhtab->ht, key, rhtab->params);

	/* if not found, return the first key */
	if (PTR_ERR(elem) == -ENOENT)
		elem = rhashtable_next_key(&rhtab->ht, NULL, rhtab->params);

	if (!elem)
		return -ENOENT;

	memcpy(next_key, elem->data, map->key_size);
	return 0;
}

rhashtable.h:
=============

static __always_inline struct rhash_head *__rhashtable_next_in_table(
	struct rhashtable *ht, struct bucket_table *tbl,
	const void *prev_key, const struct rhashtable_params params)
	__must_hold_shared(RCU)
{
	struct rhashtable_compare_arg arg = { .ht = ht, .key = prev_key };
	struct rhash_head *he;
	unsigned int b = 0;
	bool found = false;

	if (prev_key) {
		b = rht_key_hashfn(ht, tbl, prev_key, params);
		rht_for_each_rcu(he, tbl, b) {
			if (found)
				return he;
			if (params.obj_cmpfn ?
			    !params.obj_cmpfn(&arg, rht_obj(ht, he)) :
			    !rhashtable_compare(&arg, rht_obj(ht, he)))
				found = true;
		}
		if (!found)
			return ERR_PTR(-ENOENT);
		b++;
	}

	for (; b < tbl->size; b++)
		rht_for_each_rcu(he, tbl, b)
			return he;
	return NULL;
}

/**
 * rhashtable_next_key - return next element after a given key
 * @ht:		hash table
 * @prev_key:	pointer to previous key, or NULL for the first element
 * @params:	hash table parameters
 *
 * Returns the next element in best-effort iteration order, walking the
 * @tbl chain (including any future_tbl in flight). Caller must hold RCU.
 *
 * Pass @prev_key == NULL to obtain the first element. To iterate, set
 * @prev_key to the key of the previously returned element on each call,
 * and stop when NULL is returned.
 *
 * Best-effort semantics:
 *   - Across the tbl->future_tbl chain, an element being migrated may
 *     transiently appear in both tables and be observed twice.
 *   - Concurrent inserts may or may not be observed.
 *   - Termination of a full iteration loop is NOT guaranteed under
 *     adversarial continuous rehash; callers MUST tolerate skips and
 *     repeats and SHOULD bound their loop externally.
 *   - If prev_key was concurrently deleted and is not present in any
 *     in-flight table, returns ERR_PTR(-ENOENT).
 *
 * Returns entry of the next element, or NULL when iteration is exhausted
 * or ERR_PTR(-ENOENT) if prev_key is not found.
 */
static inline void *rhashtable_next_key(
	struct rhashtable *ht, const void *prev_key,
	const struct rhashtable_params params)
	__must_hold_shared(RCU)
{
	struct bucket_table *tbl;
	struct rhash_head *he;

	tbl = rht_dereference_rcu(ht->tbl, ht);
	for (; tbl; tbl = rht_dereference_rcu(tbl->future_tbl, ht)) {
		he = __rhashtable_next_in_table(ht, tbl, prev_key, params);
		if (!he)
			/*
			 * this table is exhausted, try the next one from
			 * the beginning
			 */
			prev_key = NULL;
		else if (!IS_ERR(he))
			return rht_obj(ht, he);
	}
	return he; /* NULL or -ENOENT */
}


  reply	other threads:[~2026-05-08 14:22 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-24 19:50 [PATCH bpf-next v3 00/10] bpf: Introduce resizable hash map Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 01/10] bpf: Implement resizable hashmap basic functions Mykyta Yatsenko
2026-04-24 20:40   ` sashiko-bot
2026-04-25 20:41     ` Mykyta Yatsenko
2026-04-24 20:45   ` bot+bpf-ci
2026-04-25 20:50     ` Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 02/10] rhashtable: Add rhashtable_walk_enter_from() Mykyta Yatsenko
2026-04-24 20:15   ` sashiko-bot
2026-04-24 20:45   ` bot+bpf-ci
2026-04-28 10:35   ` Herbert Xu
2026-05-05 16:57     ` Mykyta Yatsenko
2026-05-07  8:26       ` Herbert Xu
2026-05-08 14:22         ` Mykyta Yatsenko [this message]
2026-04-24 19:50 ` [PATCH bpf-next v3 03/10] bpf: Implement get_next_key() resizable hashtab Mykyta Yatsenko
2026-04-28 10:33   ` Herbert Xu
2026-04-28 13:20     ` Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 04/10] bpf: Implement batch ops and iterators for " Mykyta Yatsenko
2026-04-24 20:28   ` sashiko-bot
2026-04-25 21:24     ` Mykyta Yatsenko
2026-04-27 13:36       ` Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 05/10] bpf: Allow timers, workqueues and task_work in " Mykyta Yatsenko
2026-04-24 21:05   ` sashiko-bot
2026-04-25 21:29     ` Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 06/10] libbpf: Support resizable hashtable Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 07/10] selftests/bpf: Add basic tests for resizable hash map Mykyta Yatsenko
2026-04-24 20:02   ` sashiko-bot
2026-04-24 20:32   ` bot+bpf-ci
2026-04-24 19:50 ` [PATCH bpf-next v3 08/10] selftests/bpf: Add BPF iterator " Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 09/10] bpftool: Add rhash map documentation Mykyta Yatsenko
2026-04-24 19:50 ` [PATCH bpf-next v3 10/10] selftests/bpf: Add resizable hashmap to benchmarks Mykyta Yatsenko

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=bce63f2c-be86-4c6c-b8a9-6bea3de692ea@gmail.com \
    --to=mykyta.yatsenko5@gmail.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=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.