Path: blob/master/tools/testing/selftests/bpf/bpf_arena_alloc.h
26285 views
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */1/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */2#pragma once3#include "bpf_arena_common.h"45#ifndef __round_mask6#define __round_mask(x, y) ((__typeof__(x))((y)-1))7#endif8#ifndef round_up9#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)10#endif1112#ifdef __BPF__13#define NR_CPUS (sizeof(struct cpumask) * 8)1415static void __arena * __arena page_frag_cur_page[NR_CPUS];16static int __arena page_frag_cur_offset[NR_CPUS];1718/* Simple page_frag allocator */19static inline void __arena* bpf_alloc(unsigned int size)20{21__u64 __arena *obj_cnt;22__u32 cpu = bpf_get_smp_processor_id();23void __arena *page = page_frag_cur_page[cpu];24int __arena *cur_offset = &page_frag_cur_offset[cpu];25int offset;2627size = round_up(size, 8);28if (size >= PAGE_SIZE - 8)29return NULL;30if (!page) {31refill:32page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);33if (!page)34return NULL;35cast_kern(page);36page_frag_cur_page[cpu] = page;37*cur_offset = PAGE_SIZE - 8;38obj_cnt = page + PAGE_SIZE - 8;39*obj_cnt = 0;40} else {41cast_kern(page);42obj_cnt = page + PAGE_SIZE - 8;43}4445offset = *cur_offset - size;46if (offset < 0)47goto refill;4849(*obj_cnt)++;50*cur_offset = offset;51return page + offset;52}5354static inline void bpf_free(void __arena *addr)55{56__u64 __arena *obj_cnt;5758addr = (void __arena *)(((long)addr) & ~(PAGE_SIZE - 1));59obj_cnt = addr + PAGE_SIZE - 8;60if (--(*obj_cnt) == 0)61bpf_arena_free_pages(&arena, addr, 1);62}63#else64static inline void __arena* bpf_alloc(unsigned int size) { return NULL; }65static inline void bpf_free(void __arena *addr) {}66#endif676869