From: Hui Su <sh_def@163.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
eddyz87@gmail.com, memxor@gmail.com, martin.lau@linux.dev,
song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org,
emil@etsalapatis.com, ihor.solodrai@linux.dev, shuah@kernel.org,
yatsenko@meta.com, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH bpf 1/2] bpf: bound resizable hash map iteration
Date: Sat, 29 Aug 2026 02:33:25 +0800 [thread overview]
Message-ID: <20260828183326.3330530-1-sh_def@163.com> (raw)
rhashtable_next_key() provides a best-effort walk that may revisit
entries and is not guaranteed to terminate under sustained rehashing.
Callers performing a full iteration are expected to bound the walk
externally.
bpf_each_rhash_elem() currently loops until rhashtable_next_key()
returns NULL, leaving callback execution without a finite bound. Bound
one walk by map->max_entries while preserving the existing best-effort
semantics.
Use map->max_entries as the iteration budget. Duplicate visits may
consume the budget and cause the walk to stop before all keys are
observed, but RHASH iteration already permits missed elements under
concurrent mutation.
This is reproducible with concurrent updates and deletes triggering
rehash. With max_entries=4096, one walk invoked the callback 5239 times
on an unpatched kernel. With the bound in place, callback invocations did
not exceed 4096 in the same stress test.
Fixes: 818e00848227 ("bpf: Implement iteration ops for resizable hashtab")
Signed-off-by: Hui Su <sh_def@163.com>
---
kernel/bpf/hashtab.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index d40cb5dd446c..3772e63f2f12 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -3198,7 +3198,7 @@ static long bpf_each_rhash_elem(struct bpf_map *map, bpf_callback_t callback_fn,
struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
void *prev_key = NULL;
struct rhtab_elem *elem;
- int num_elems = 0;
+ u32 num_elems = 0;
u64 ret = 0;
cant_migrate();
@@ -3212,7 +3212,8 @@ static long bpf_each_rhash_elem(struct bpf_map *map, bpf_callback_t callback_fn,
* elements are deleted/inserted, there may be missed or duplicate
* elements visited.
*/
- while ((elem = rhashtable_next_key(&rhtab->ht, prev_key))) {
+ while (num_elems < map->max_entries &&
+ (elem = rhashtable_next_key(&rhtab->ht, prev_key))) {
if (IS_ERR(elem))
break;
num_elems++;
base-commit: c20313e98b04ce543936431b6122dd639d3a8346
--
2.54.0
next reply other threads:[~2026-08-28 18:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 18:33 Hui Su [this message]
2026-08-28 18:33 ` [PATCH bpf 2/2] selftests/bpf: add RHASH iteration stress test Hui Su
2026-08-28 19:20 ` bot+bpf-ci
2026-08-28 18:46 ` [PATCH bpf 1/2] bpf: bound resizable hash map iteration sashiko-bot
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=20260828183326.3330530-1-sh_def@163.com \
--to=sh_def@163.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=yatsenko@meta.com \
--cc=yonghong.song@linux.dev \
/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).