All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Tianyi Chen" <hi@tychen.cc>, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v10 1/2] bpftool: Use batch lookups for map dumps
Date: Wed, 11 Nov 2026 07:38:31 +0000	[thread overview]
Message-ID: <sashiko-outbox-208531@kernel.org> (raw)
In-Reply-To: <074a359a044d121b4d85d5b15b7740bc9a9f1073.1794380384.git.hi@tychen.cc>

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] bpftool: silent map dump truncation on RHASH in
  dump_map_batch()
--

commit 7f62f4c69f650b2c84d0fbb5439eadc6c97b8aea
Author: Tianyi Chen <hi@tychen.cc>

bpftool: Use batch lookups for map dumps

This commit updates map_dump() to use BPF_MAP_LOOKUP_BATCH in 1 MiB batches
and fall back to bpf_map_get_next_key() after the last printed key if a
batch lookup fails.

Link: https://github.com/libbpf/bpftool/issues/63

> diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
> index 4b65edf74859b..c5c56323f0623 100644
> --- a/tools/bpf/bpftool/map.c
> +++ b/tools/bpf/bpftool/map.c
[ ... ]
> @@ -763,10 +761,75 @@ static int dump_map_elem(int fd, void *key, void *value,
>  	} else {
>  		print_entry_plain(map_info, key, value, cpu_ids, cpu_cnt);
>  	}
> +}
>
> +static int dump_map_elem(int fd, void *key, void *value,
> +			 struct bpf_map_info *map_info, struct btf *btf,
> +			 json_writer_t *btf_wtr, const int *cpu_ids, int cpu_cnt)
> +{
> +	if (bpf_map_lookup_elem(fd, key, value)) {
> +		print_entry_error(map_info, key, errno);
> +		return -1;
> +	}
> +
> +	print_map_elem(key, value, map_info, btf, btf_wtr, cpu_ids, cpu_cnt);
>  	return 0;
>  }
>
> +#define MAP_DUMP_BATCH_BYTES (1U << 20)
> +
> +/*
> + * Print the elements returned by batched lookups, leaving the last one in
> + * @key. Return true at the end of the map. After any error, the caller
> + * continues with bpf_map_get_next_key(), which walks the map in the same order.
> + * The caller must ensure that key_size + value_size is non-zero.
> + */
> +static bool dump_map_batch(int fd, void *key, void *value,
> +			   struct bpf_map_info *info, struct btf *btf,
> +			   json_writer_t *wtr, const int *cpu_ids, int cpu_cnt,
> +			   unsigned int *num_elems)
> +{
> +	size_t value_size = map_value_size(info);
> +	void *keys, *values, *batch, *in_batch = NULL;
> +	__u32 capacity, count, i;
> +	bool done = false;
> +	int err;
> +
> +	capacity = min(MAP_DUMP_BATCH_BYTES / (info->key_size + value_size),
> +		       (size_t)info->max_entries);
> +	if (!capacity)
> +		return false;
> +
> +	/* Hash table batch cursors are u32 bucket indices; other maps use keys. */
> +	batch = malloc(max(info->key_size, 4U));
> +	keys = malloc((size_t)capacity * info->key_size);
> +	values = malloc((size_t)capacity * value_size);
> +	if (!batch || !keys || !values)
> +		goto out;
> +
> +	do {
> +		count = capacity;
> +		err = bpf_map_lookup_batch(fd, in_batch, batch, keys, values,
> +					   &count, NULL);
> +		if (err && err != -ENOENT)
> +			goto out;
> +		for (i = 0; i < count; i++) {
> +			/* Preserve alignment for odd-sized BTF keys and values. */
> +			memcpy(key, keys + (size_t)i * info->key_size, info->key_size);
> +			memcpy(value, values + (size_t)i * value_size, value_size);
> +			print_map_elem(key, value, info, btf, wtr, cpu_ids, cpu_cnt);
> +		}
> +		*num_elems += count;
> +		in_batch = batch;
> +	} while (!err);
> +	done = true;

[Severity: Medium]
As reported by bot+bpf-ci@kernel.org on v9 [1], can dump_map_batch()
silently truncate a BPF_MAP_TYPE_RHASH dump when an element is deleted
concurrently?

For BPF_MAP_TYPE_RHASH, __rhtab_map_lookup_and_delete_batch() holds only
rcu_read_lock().  If dst_key is removed between copying elem->data and
calling rhashtable_next_key(&rhtab->ht, dst_key), rhashtable_next_key()
returns ERR_PTR(-ENOENT), which leaves has_next_cursor false and causes
__rhtab_map_lookup_and_delete_batch() to return -ENOENT early:

kernel/bpf/hashtab.c:__rhtab_map_lookup_and_delete_batch() {
	...
	while (elem && !IS_ERR(elem) && total < max_count) {
		memcpy(dst_key, elem->data, key_size);
		...
		elem = rhashtable_next_key(&rhtab->ht, dst_key);
		...
	}

	if (elem && !IS_ERR(elem)) {
		/* Stash next-to-process key as cursor for the next batch. */
		memcpy(cursor, elem->data, key_size);
		has_next_cursor = true;
	}
	...
	/* No more elements after this batch. */
	if (!has_next_cursor)
		ret = -ENOENT;
}

Because dump_map_batch() treats -ENOENT as end-of-map and returns true,
map_dump() skips the bpf_map_get_next_key() fallback loop (where
rhtab_map_get_next_key() restarts from NULL on -ENOENT) and exits with
success after printing only part of the map.

[1] https://lore.kernel.org/r/33b057d852c258c157f6aa31e45083418944efe0efaad1d72bcb5513205a67f6@mail.kernel.org

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794380384.git.hi@tychen.cc?part=1

  reply	other threads:[~2026-11-11  7:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11  7:18 [PATCH bpf-next v10 0/2] bpftool: Use batch lookups for map dumps Tianyi Chen
2026-11-11  7:18 ` [PATCH bpf-next v10 1/2] " Tianyi Chen
2026-11-11  7:38   ` sashiko-bot [this message]
2026-11-11  7:18 ` [PATCH bpf-next v10 2/2] selftests/bpf: Check bpftool batch " Tianyi Chen

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=sashiko-outbox-208531@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=hi@tychen.cc \
    --cc=sashiko-reviews@lists.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 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.