lib/stackdepot.c
Source file repositories/reference/linux-study-clean/lib/stackdepot.c
File Facts
- System
- Linux kernel
- Corpus path
lib/stackdepot.c- Extension
.c- Size
- 24634 bytes
- Lines
- 879
- Domain
- Kernel Services
- Bucket
- lib
- Inferred role
- Kernel Services: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/debugfs.hlinux/gfp.hlinux/jhash.hlinux/kernel.hlinux/kmsan.hlinux/list.hlinux/mm.hlinux/mutex.hlinux/poison.hlinux/printk.hlinux/rculist.hlinux/rcupdate.hlinux/refcount.hlinux/slab.hlinux/spinlock.hlinux/stacktrace.hlinux/stackdepot.hlinux/string.hlinux/types.hlinux/memblock.hlinux/kasan-enabled.h
Detected Declarations
enum depot_counter_idfunction disable_stack_depotfunction parse_max_poolsfunction stack_depot_request_early_initfunction init_stack_tablefunction stack_depot_early_initfunction stack_depot_initfunction stack_depot_initfunction depot_init_poolfunction depot_keep_new_poolfunction depot_stack_record_sizefunction depot_alloc_stackfunction depot_free_stackfunction hash_stackfunction stackdepot_memcmpfunction list_for_each_entry_rcufunction stack_depot_save_flagsfunction stack_depot_savefunction stack_depot_fetchfunction stack_depot_putfunction stack_depot_printfunction stack_depot_snprintfunction stack_depot_set_extra_bitsfunction stack_depot_get_extra_bitsfunction stats_showfunction depot_debugfs_initexport stack_depot_initexport stack_depot_save_flagsexport stack_depot_saveexport stack_depot_fetchexport stack_depot_putexport stack_depot_printexport stack_depot_snprintexport stack_depot_set_extra_bitsexport stack_depot_get_extra_bits
Annotated Snippet
if (new) {
/*
* This releases the stack record into the bucket and
* makes it visible to readers in find_stack().
*/
list_add_rcu(&new->hash_list, bucket);
found = new;
}
}
if (prealloc) {
/*
* Either stack depot already contains this stack trace, or
* depot_alloc_stack() did not consume the preallocated memory.
* Try to keep the preallocated memory for future.
*/
depot_keep_new_pool(&prealloc);
}
printk_deferred_exit();
raw_spin_unlock_irqrestore(&pool_lock, flags);
exit:
if (prealloc) {
/* Stack depot didn't use this memory, free it. */
if (!allow_spin)
free_pages_nolock(virt_to_page(prealloc), DEPOT_POOL_ORDER);
else
free_pages((unsigned long)prealloc, DEPOT_POOL_ORDER);
}
if (found)
handle = found->handle.handle;
return handle;
}
EXPORT_SYMBOL_GPL(stack_depot_save_flags);
depot_stack_handle_t stack_depot_save(unsigned long *entries,
unsigned int nr_entries,
gfp_t alloc_flags)
{
return stack_depot_save_flags(entries, nr_entries, alloc_flags,
STACK_DEPOT_FLAG_CAN_ALLOC);
}
EXPORT_SYMBOL_GPL(stack_depot_save);
struct stack_record *__stack_depot_get_stack_record(depot_stack_handle_t handle)
{
if (!handle)
return NULL;
return depot_fetch_stack(handle);
}
unsigned int stack_depot_fetch(depot_stack_handle_t handle,
unsigned long **entries)
{
struct stack_record *stack;
*entries = NULL;
/*
* Let KMSAN know *entries is initialized. This shall prevent false
* positive reports if instrumented code accesses it.
*/
kmsan_unpoison_memory(entries, sizeof(*entries));
if (!handle || stack_depot_disabled)
return 0;
stack = depot_fetch_stack(handle);
/*
* Should never be NULL, otherwise this is a use-after-put (or just a
* corrupt handle).
*/
if (WARN(!stack, "corrupt handle or use after stack_depot_put()"))
return 0;
*entries = stack->entries;
return stack->size;
}
EXPORT_SYMBOL_GPL(stack_depot_fetch);
void stack_depot_put(depot_stack_handle_t handle)
{
struct stack_record *stack;
if (!handle || stack_depot_disabled)
return;
stack = depot_fetch_stack(handle);
/*
* Should always be able to find the stack record, otherwise this is an
Annotation
- Immediate include surface: `linux/debugfs.h`, `linux/gfp.h`, `linux/jhash.h`, `linux/kernel.h`, `linux/kmsan.h`, `linux/list.h`, `linux/mm.h`, `linux/mutex.h`.
- Detected declarations: `enum depot_counter_id`, `function disable_stack_depot`, `function parse_max_pools`, `function stack_depot_request_early_init`, `function init_stack_table`, `function stack_depot_early_init`, `function stack_depot_init`, `function stack_depot_init`, `function depot_init_pool`, `function depot_keep_new_pool`.
- Atlas domain: Kernel Services / lib.
- Implementation status: integration 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.