From: sashiko-bot@kernel.org
To: "Emil Tsalapatis" <emil@etsalapatis.com>, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v4 5/9] selftests/bpf: libarena: Add buddy per-CPU caches
Date: Mon, 09 Nov 2026 18:38:48 +0000 [thread overview]
Message-ID: <sashiko-outbox-205430@kernel.org> (raw)
In-Reply-To: <20261109182055.7581-6-emil@etsalapatis.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Medium] selftests/bpf: conflicting prototype for buddy_alloc_memory()
- [Low] selftests/bpf: buddy_alloc_nogrow() bypasses buddy_cache_alloc()
- [Low] selftests/bpf: missing static on buddy_cache_alloc() and
buddy_cache_free()
--
commit 2da1f713f762ba4737b95c532cd5e6f183f3f061
Author: Emil Tsalapatis <emil@etsalapatis.com>
selftests/bpf: libarena: Add buddy per-CPU caches
This commit adds per-CPU LIFO array caches to the libarena buddy allocator
for the eight smallest allocation orders so small allocations and frees can
avoid taking the central buddy lock.
> diff --git a/tools/testing/selftests/bpf/libarena/src/buddy.bpf.c b/tools/testing/selftests/bpf/libarena/src/buddy.bpf.c
> index 514d0a59eaff5..13c55cf53e524 100644
> --- a/tools/testing/selftests/bpf/libarena/src/buddy.bpf.c
> +++ b/tools/testing/selftests/bpf/libarena/src/buddy.bpf.c
> @@ -38,18 +41,162 @@
> * and their allocation state. It also includes the freelist
> * heads for the allocation itself.
> */
> +static u8 idx_get_order(struct buddy_chunk __arena *chunk, u64 idx);
> +static int idx_is_allocated(struct buddy_chunk __arena *chunk, u64 idx, bool *allocated);
> +static u64 arena_next_pow2(__u64 n);
> +static u64 size_to_order(size_t size);
> +static void __arena *buddy_alloc_memory(struct buddy __arena *buddy, size_t size,
> + int order, size_t norder);
> +static int buddy_free_unlocked(struct buddy __arena *buddy, u64 addr);
[Severity: Medium]
Does this forward declaration of buddy_alloc_memory() break the build at
this commit? It omits the fifth parameter (bool grow) from the definition:
tools/testing/selftests/bpf/libarena/src/buddy.bpf.c:
static void __arena *buddy_alloc_memory(struct buddy __arena *buddy, size_t size,
int order, size_t norder, bool grow)
Although the later commit "selftests/bpf: libarena: Handle NMI reentrancy"
adds bool grow to the prototype, this commit fails to compile with
conflicting types and breaks bisection. Note also that buddy_alloc_memory(),
arena_next_pow2(), size_to_order() and buddy_free_unlocked() are not called
before their definitions in this patch.
[ ... ]
> +void __arena *buddy_cache_alloc(struct buddy __arena *buddy, size_t order)
> +{
> + struct buddy_cache __arena *cache;
> + void __arena *address = NULL;
> +
> + if (!buddy_order_cached(order))
> + return NULL;
> +
> + cache = buddy_cache_enter(buddy);
> + if (!cache)
> + return NULL;
> +
> + address = buddy_cache_pop(cache, order);
> + buddy_cache_exit(cache);
> +
> + return address;
> +}
> +
> +/*
> + * Retrieve the order of an allocation from the address. Reject addresses
> + * that do not start an allocated block so that the locked path can report
> + * them, instead of caching memory that overlaps a live allocation. Cached
> + * objects stay marked as allocated, so freeing an object that is already
> + * cached is not detected.
> + */
> +static int buddy_cache_get_order(void __arena *addr)
> +{
> + struct buddy_chunk __arena *chunk;
> + bool allocated;
> + u64 idx;
> +
> + if ((u64)addr & (BUDDY_MIN_ALLOC_BYTES - 1))
> + return BUDDY_CHUNK_NUM_ORDERS;
>
> + chunk = (void __arena *)((u64)addr & ~BUDDY_CHUNK_OFFSET_MASK);
> + idx = ((u64)addr & BUDDY_CHUNK_OFFSET_MASK) / BUDDY_MIN_ALLOC_BYTES;
> +
> + if (idx_is_allocated(chunk, idx, &allocated) || !allocated)
> + return BUDDY_CHUNK_NUM_ORDERS;
> +
> + return idx_get_order(chunk, idx);
> +}
> +
> +__always_inline int buddy_cache_free(struct buddy __arena *buddy, void __arena *addr)
[Severity: Low]
Should buddy_cache_alloc() and buddy_cache_free() be marked static like the
other internal cache helpers in buddy.bpf.c? Neither helper is declared in
buddy.h or referenced outside this file, and omitting static prevents
buddy_cache_alloc() from being inlined as a local helper into buddy_alloc().
[ ... ]
> @@ -819,7 +1012,18 @@ static void __arena *buddy_alloc_memory(struct buddy __arena *buddy, size_t size
> __weak
> void __arena *buddy_alloc(struct buddy __arena *buddy, size_t size)
> {
> - return buddy_alloc_memory(buddy, size, size_to_order(size), 0, true);
> + void __arena *address;
> + int order;
> +
> + if (!buddy)
> + return NULL;
> +
> + order = size_to_order(size);
> + address = buddy_cache_alloc(buddy, order);
> + if (address)
> + return address;
> +
> + return buddy_alloc_memory(buddy, size, order, 0, true);
> }
>
> __weak
[Severity: Low]
Should buddy_alloc_nogrow() also check buddy_cache_alloc() before falling
back to buddy_alloc_memory()?
tools/testing/selftests/bpf/libarena/src/buddy.bpf.c:
__weak
void __arena *buddy_alloc_nogrow(struct buddy __arena *buddy, size_t size)
{
return buddy_alloc_memory(buddy, size, size_to_order(size), 0, false);
}
When buddy_free() caches a small object, the object stays marked allocated
and off the chunk freelists. Because buddy_alloc_nogrow() calls
buddy_alloc_memory() directly, it always takes the central buddy lock and
can return NULL when the chunk freelists are empty even though free objects
of the requested order are sitting in the local per-CPU cache.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109182055.7581-1-emil@etsalapatis.com?part=5
next prev parent reply other threads:[~2026-11-09 18:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 18:20 [PATCH bpf-next v4 0/9] bpf libarena allocator improvements Emil Tsalapatis
2026-11-09 18:20 ` [PATCH bpf-next v4 1/9] selftests/bpf: libarena: Add bulk buddy allocation helpers Emil Tsalapatis
2026-11-09 18:20 ` [PATCH bpf-next v4 2/9] selftests/bpf: Add a parallel buddy allocator benchmark Emil Tsalapatis
2026-11-09 18:20 ` [PATCH bpf-next v4 3/9] selftests/bpf: libarena: Make spinlock trylock match arena_spin_unlock Emil Tsalapatis
2026-11-09 18:29 ` sashiko-bot
2026-11-09 18:20 ` [PATCH bpf-next v4 4/9] selftests/bpf: libarena: Raise arena spinlock CPU limits Emil Tsalapatis
2026-11-09 18:32 ` sashiko-bot
2026-11-09 18:20 ` [PATCH bpf-next v4 5/9] selftests/bpf: libarena: Add buddy per-CPU caches Emil Tsalapatis
2026-11-09 18:38 ` sashiko-bot [this message]
2026-11-09 18:20 ` [PATCH bpf-next v4 6/9] selftests/bpf: libarena: Handle NMI reentrancy Emil Tsalapatis
2026-11-09 18:42 ` sashiko-bot
2026-11-09 19:05 ` bot+bpf-ci
2026-11-09 19:08 ` Emil Tsalapatis
2026-11-09 18:20 ` [PATCH bpf-next v4 7/9] selftests/bpf: libarena: Refill local caches in batches Emil Tsalapatis
2026-11-09 18:20 ` [PATCH bpf-next v4 8/9] selftests/bpf: libarena: Add a transfer cache Emil Tsalapatis
2026-11-09 18:20 ` [PATCH bpf-next v4 9/9] selftests/bpf: libarena: Cover buddy cache fast paths Emil Tsalapatis
2026-11-09 19:05 ` bot+bpf-ci
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-205430@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=emil@etsalapatis.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox