kernel/static_call_inline.c
Source file repositories/reference/linux-study-clean/kernel/static_call_inline.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/static_call_inline.c- Extension
.c- Size
- 13320 bytes
- Lines
- 567
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration 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.
- 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/init.hlinux/static_call.hlinux/bug.hlinux/smp.hlinux/sort.hlinux/slab.hlinux/module.hlinux/cpu.hlinux/processor.hasm/sections.h
Detected Declarations
function early_initcallfunction static_call_lockfunction static_call_unlockfunction __static_call_keyfunction static_call_is_initfunction static_call_is_tailfunction static_call_set_initfunction static_call_site_cmpfunction static_call_site_swapfunction static_call_sort_entriesfunction static_call_key_has_modsfunction __static_call_updatefunction __static_call_initfunction vmlinuxfunction addr_conflictfunction __static_call_text_reservedfunction __static_call_mod_text_reservedfunction scoped_guardfunction tramp_key_lookupfunction static_call_add_modulefunction static_call_del_modulefunction static_call_module_notifyfunction __static_call_mod_text_reservedfunction static_call_text_reservedfunction static_call_initfunction func_afunction func_bfunction test_static_call_initexport __static_call_update
Annotated Snippet
if (!site_mod->sites) {
/*
* This can happen if the static call key is defined in
* a module which doesn't use it.
*
* It also happens in the has_mods case, where the
* 'first' entry has no sites associated with it.
*/
continue;
}
stop = __stop_static_call_sites;
if (mod) {
#ifdef CONFIG_MODULES
stop = mod->static_call_sites +
mod->num_static_call_sites;
init = mod->state == MODULE_STATE_COMING;
#endif
}
for (site = site_mod->sites;
site < stop && static_call_key(site) == key; site++) {
void *site_addr = static_call_addr(site);
if (!init && static_call_is_init(site))
continue;
if (!kernel_text_address((unsigned long)site_addr)) {
/*
* This skips patching built-in __exit, which
* is part of init_section_contains() but is
* not part of kernel_text_address().
*
* Skipping built-in __exit is fine since it
* will never be executed.
*/
WARN_ONCE(!static_call_is_init(site),
"can't patch static call site at %pS",
site_addr);
continue;
}
arch_static_call_transform(site_addr, tramp, func,
static_call_is_tail(site));
}
}
done:
static_call_unlock();
cpus_read_unlock();
}
EXPORT_SYMBOL_GPL(__static_call_update);
static int __static_call_init(struct module *mod,
struct static_call_site *start,
struct static_call_site *stop)
{
struct static_call_site *site;
struct static_call_key *key, *prev_key = NULL;
struct static_call_mod *site_mod;
if (start == stop)
return 0;
static_call_sort_entries(start, stop);
for (site = start; site < stop; site++) {
void *site_addr = static_call_addr(site);
if ((mod && within_module_init((unsigned long)site_addr, mod)) ||
(!mod && init_section_contains(site_addr, 1)))
static_call_set_init(site);
key = static_call_key(site);
if (key != prev_key) {
prev_key = key;
/*
* For vmlinux (!mod) avoid the allocation by storing
* the sites pointer in the key itself. Also see
* __static_call_update()'s @first.
*
* This allows architectures (eg. x86) to call
* static_call_init() before memory allocation works.
*/
if (!mod) {
key->sites = site;
key->type |= 1;
goto do_transform;
Annotation
- Immediate include surface: `linux/init.h`, `linux/static_call.h`, `linux/bug.h`, `linux/smp.h`, `linux/sort.h`, `linux/slab.h`, `linux/module.h`, `linux/cpu.h`.
- Detected declarations: `function early_initcall`, `function static_call_lock`, `function static_call_unlock`, `function __static_call_key`, `function static_call_is_init`, `function static_call_is_tail`, `function static_call_set_init`, `function static_call_site_cmp`, `function static_call_site_swap`, `function static_call_sort_entries`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- 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.