| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- /* 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
|