mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-09 06:14:34 +02:00
The BPF selftest headers include functionality that is specific to arenas and is required by libarena. Keep libarena self-contained by moving all functionality into its include/ directory. Also add libarena/include to the standard include paths for the selftests to make the moved headers easy to access by existing selftests. Some functionality is required by libarena but not strictly arena-related. We still move it to the libarena/include path, which is an upgrade from directly accessing them from the selftests/bpf directory using relative paths. A new bpf_may_goto.h file is split off of bpf_experimental.h. bpf_arena_spin_lock.h and bpf_arena_common.h are moved to libarena/include. bpf_atomic.h is also moved to libarena because it is necessary for arena spinlocks. For bpf_arena_spin_lock.h, mark the spinlock state array as __weak to define the spinlock state array in the header while also being compatible with multi-compilation unit programs. While we're at it, we remove unnecessary definitions from existing test programs. Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/r/20260426190338.4615-4-emil@etsalapatis.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
68 lines
1.6 KiB
C
68 lines
1.6 KiB
C
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
|
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
|
|
#pragma once
|
|
#include <bpf_arena_common.h>
|
|
|
|
#ifndef __round_mask
|
|
#define __round_mask(x, y) ((__typeof__(x))((y)-1))
|
|
#endif
|
|
#ifndef round_up
|
|
#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
|
|
#endif
|
|
|
|
#ifdef __BPF__
|
|
#define NR_CPUS (sizeof(struct cpumask) * 8)
|
|
|
|
static void __arena * __arena page_frag_cur_page[NR_CPUS];
|
|
static int __arena page_frag_cur_offset[NR_CPUS];
|
|
|
|
/* Simple page_frag allocator */
|
|
static inline void __arena* bpf_alloc(unsigned int size)
|
|
{
|
|
__u64 __arena *obj_cnt;
|
|
__u32 cpu = bpf_get_smp_processor_id();
|
|
void __arena *page = page_frag_cur_page[cpu];
|
|
int __arena *cur_offset = &page_frag_cur_offset[cpu];
|
|
int offset;
|
|
|
|
size = round_up(size, 8);
|
|
if (size >= PAGE_SIZE - 8)
|
|
return NULL;
|
|
if (!page) {
|
|
refill:
|
|
page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
|
|
if (!page)
|
|
return NULL;
|
|
cast_kern(page);
|
|
page_frag_cur_page[cpu] = page;
|
|
*cur_offset = PAGE_SIZE - 8;
|
|
obj_cnt = page + PAGE_SIZE - 8;
|
|
*obj_cnt = 0;
|
|
} else {
|
|
cast_kern(page);
|
|
obj_cnt = page + PAGE_SIZE - 8;
|
|
}
|
|
|
|
offset = *cur_offset - size;
|
|
if (offset < 0)
|
|
goto refill;
|
|
|
|
(*obj_cnt)++;
|
|
*cur_offset = offset;
|
|
return page + offset;
|
|
}
|
|
|
|
static inline void bpf_free(void __arena *addr)
|
|
{
|
|
__u64 __arena *obj_cnt;
|
|
|
|
addr = (void __arena *)(((long)addr) & ~(PAGE_SIZE - 1));
|
|
obj_cnt = addr + PAGE_SIZE - 8;
|
|
if (--(*obj_cnt) == 0)
|
|
bpf_arena_free_pages(&arena, addr, 1);
|
|
}
|
|
#else
|
|
static inline void __arena* bpf_alloc(unsigned int size) { return NULL; }
|
|
static inline void bpf_free(void __arena *addr) {}
|
|
#endif
|