[PATCH v2 05/16] bpf: Mark the bpf_mem_alloc fast path helpers notrace

From: Song Liu

Date: Thu Oct 22 2026 - 21:13:51 EST


unit_alloc(), unit_free() and unit_free_rcu() are notrace so that BPF
programs cannot attach to them and corrupt the per-CPU free lists, as
the comment above unit_alloc() says. To take and release c->active and
to update the free lists, they call local_inc_return()
(local_add_return() on x86), local_dec(), __llist_add() and
llist_add(). These are plain inline functions, as are
__llist_add_batch() and llist_add_batch(), which the llist helpers call.
An out-of-line copy of any of them is untraced only because inline
implies notrace.

Mark them notrace explicitly. No functional change.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Song Liu <song@xxxxxxxxxx>
---
arch/x86/include/asm/local.h | 4 ++--
include/linux/llist.h | 16 ++++++++--------
2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
index 1749c4481000..66f2cd57160c 100644
--- a/arch/x86/include/asm/local.h
+++ b/arch/x86/include/asm/local.h
@@ -22,7 +22,7 @@ static inline void notrace local_inc(local_t *l)
: "+m" (l->a.counter));
}

-static inline void local_dec(local_t *l)
+static inline void notrace local_dec(local_t *l)
{
asm volatile(_ASM_DEC "%0"
: "+m" (l->a.counter));
@@ -103,7 +103,7 @@ static inline bool local_add_negative(long i, local_t *l)
*
* Atomically adds @i to @l and returns @i + @l
*/
-static inline long local_add_return(long i, local_t *l)
+static inline long notrace local_add_return(long i, local_t *l)
{
long __i = i;
asm volatile(_ASM_XADD "%0, %1"
diff --git a/include/linux/llist.h b/include/linux/llist.h
index 8846b7709669..53bc48f6b956 100644
--- a/include/linux/llist.h
+++ b/include/linux/llist.h
@@ -231,9 +231,9 @@ static inline struct llist_node *llist_next(struct llist_node *node)
*
* Return whether list is empty before adding.
*/
-static inline bool llist_add_batch(struct llist_node *new_first,
- struct llist_node *new_last,
- struct llist_head *head)
+static inline bool notrace llist_add_batch(struct llist_node *new_first,
+ struct llist_node *new_last,
+ struct llist_head *head)
{
struct llist_node *first = READ_ONCE(head->first);

@@ -244,9 +244,9 @@ static inline bool llist_add_batch(struct llist_node *new_first,
return !first;
}

-static inline bool __llist_add_batch(struct llist_node *new_first,
- struct llist_node *new_last,
- struct llist_head *head)
+static inline bool notrace __llist_add_batch(struct llist_node *new_first,
+ struct llist_node *new_last,
+ struct llist_head *head)
{
new_last->next = head->first;
head->first = new_first;
@@ -260,12 +260,12 @@ static inline bool __llist_add_batch(struct llist_node *new_first,
*
* Returns true if the list was empty prior to adding this entry.
*/
-static inline bool llist_add(struct llist_node *new, struct llist_head *head)
+static inline bool notrace llist_add(struct llist_node *new, struct llist_head *head)
{
return llist_add_batch(new, new, head);
}

-static inline bool __llist_add(struct llist_node *new, struct llist_head *head)
+static inline bool notrace __llist_add(struct llist_node *new, struct llist_head *head)
{
return __llist_add_batch(new, new, head);
}
--
2.53.0-Meta