kernel/bpf/stackmap.c
Source file repositories/reference/linux-study-clean/kernel/bpf/stackmap.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/bpf/stackmap.c- Extension
.c- Size
- 26042 bytes
- Lines
- 974
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bpf.hlinux/jhash.hlinux/filter.hlinux/kernel.hlinux/stacktrace.hlinux/perf_event.hlinux/btf_ids.hlinux/buildid.hlinux/mmap_lock.hpercpu_freelist.hmmap_unlock_work.h
Detected Declarations
struct stack_map_bucketstruct bpf_stack_mapstruct stack_map_vma_lockfunction stack_map_use_build_idfunction stack_map_data_sizefunction stack_map_calculate_max_depthfunction prealloc_elems_and_freelistfunction fetch_build_idfunction stack_map_build_id_set_ipfunction stack_map_build_id_offsetfunction stack_map_build_id_set_validfunction get_filefunction stack_map_unlock_vmafunction stack_map_get_build_id_offset_sleepablefunction previousfunction stack_map_get_build_id_offsetfunction stackfunction get_callchain_entry_for_taskfunction __bpf_get_stackidfunction count_kernel_ipfunction __bpf_get_stackfunction __bpf_get_task_stackfunction stack_map_lookup_and_delete_elemfunction bpf_stackmap_extractfunction stack_map_get_next_keyfunction stack_map_update_elemfunction stack_map_delete_elemfunction stack_map_freefunction stack_map_mem_usage
Annotated Snippet
struct stack_map_bucket {
struct pcpu_freelist_node fnode;
u32 hash;
u32 nr;
u64 data[];
};
struct bpf_stack_map {
struct bpf_map map;
void *elems;
struct pcpu_freelist freelist;
u32 n_buckets;
struct stack_map_bucket *buckets[] __counted_by(n_buckets);
};
static inline bool stack_map_use_build_id(struct bpf_map *map)
{
return (map->map_flags & BPF_F_STACK_BUILD_ID);
}
static inline int stack_map_data_size(struct bpf_map *map)
{
return stack_map_use_build_id(map) ?
sizeof(struct bpf_stack_build_id) : sizeof(u64);
}
/**
* stack_map_calculate_max_depth - Calculate maximum allowed stack trace depth
* @size: Size of the buffer/map value in bytes
* @elem_size: Size of each stack trace element
* @flags: BPF stack trace flags (BPF_F_USER_STACK, BPF_F_USER_BUILD_ID, ...)
*
* Return: Maximum number of stack trace entries that can be safely stored
*/
static u32 stack_map_calculate_max_depth(u32 size, u32 elem_size, u64 flags)
{
u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
u32 max_depth;
u32 curr_sysctl_max_stack = READ_ONCE(sysctl_perf_event_max_stack);
max_depth = size / elem_size;
max_depth += skip;
if (max_depth > curr_sysctl_max_stack)
return curr_sysctl_max_stack;
return max_depth;
}
static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
{
u64 elem_size = sizeof(struct stack_map_bucket) +
(u64)smap->map.value_size;
int err;
smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries,
smap->map.numa_node);
if (!smap->elems)
return -ENOMEM;
err = pcpu_freelist_init(&smap->freelist);
if (err)
goto free_elems;
pcpu_freelist_populate(&smap->freelist, smap->elems, elem_size,
smap->map.max_entries);
return 0;
free_elems:
bpf_map_area_free(smap->elems);
return err;
}
/* Called from syscall */
static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
{
u32 value_size = attr->value_size;
struct bpf_stack_map *smap;
u64 cost, n_buckets;
int err;
if (attr->map_flags & ~STACK_CREATE_FLAG_MASK)
return ERR_PTR(-EINVAL);
/* check sanity of attributes */
if (attr->max_entries == 0 || attr->key_size != 4 ||
value_size < 8 || value_size % 8)
return ERR_PTR(-EINVAL);
BUILD_BUG_ON(sizeof(struct bpf_stack_build_id) % sizeof(u64));
if (attr->map_flags & BPF_F_STACK_BUILD_ID) {
Annotation
- Immediate include surface: `linux/bpf.h`, `linux/jhash.h`, `linux/filter.h`, `linux/kernel.h`, `linux/stacktrace.h`, `linux/perf_event.h`, `linux/btf_ids.h`, `linux/buildid.h`.
- Detected declarations: `struct stack_map_bucket`, `struct bpf_stack_map`, `struct stack_map_vma_lock`, `function stack_map_use_build_id`, `function stack_map_data_size`, `function stack_map_calculate_max_depth`, `function prealloc_elems_and_freelist`, `function fetch_build_id`, `function stack_map_build_id_set_ip`, `function stack_map_build_id_offset`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.