kernel/jump_label.c
Source file repositories/reference/linux-study-clean/kernel/jump_label.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/jump_label.c- Extension
.c- Size
- 23592 bytes
- Lines
- 949
- 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/memory.hlinux/uaccess.hlinux/module.hlinux/list.hlinux/slab.hlinux/sort.hlinux/err.hlinux/static_key.hlinux/jump_label_ratelimit.hlinux/bug.hlinux/cpu.hasm/sections.h
Detected Declarations
struct static_key_modfunction jump_label_lockfunction jump_label_unlockfunction jump_label_cmpfunction jump_label_swapfunction jump_label_sort_entriesfunction static_key_countfunction static_key_fast_inc_not_disabledfunction static_key_slow_inc_cpuslockedfunction static_key_slow_incfunction static_key_enable_cpuslockedfunction static_key_enablefunction static_key_disable_cpuslockedfunction static_key_disablefunction static_key_dec_not_onefunction __static_key_slow_dec_cpuslockedfunction __static_key_slow_decfunction jump_label_update_timeoutfunction static_key_slow_decfunction static_key_slow_dec_cpuslockedfunction __static_key_slow_dec_deferredfunction __static_key_deferred_flushfunction jump_label_rate_limitfunction addr_conflictfunction __jump_label_text_reservedfunction arch_jump_label_transform_staticfunction static_key_typefunction static_key_linkedfunction static_key_clear_linkedfunction static_key_set_linkedfunction static_key_set_entriesfunction jump_label_typefunction jump_label_can_updatefunction __jump_label_updatefunction __jump_label_updatefunction jump_label_initfunction static_key_sealedfunction static_key_sealfunction jump_label_init_rofunction jump_label_init_typefunction static_key_set_entriesfunction __jump_label_mod_text_reservedfunction scoped_guardfunction __jump_label_mod_updatefunction jump_label_add_modulefunction jump_label_del_modulefunction jump_label_module_notifyfunction jump_label_init_module
Annotated Snippet
struct static_key_mod {
struct static_key_mod *next;
struct jump_entry *entries;
struct module *mod;
};
static inline struct static_key_mod *static_key_mod(struct static_key *key)
{
WARN_ON_ONCE(!static_key_linked(key));
return (struct static_key_mod *)(key->type & ~JUMP_TYPE_MASK);
}
/***
* key->type and key->next are the same via union.
* This sets key->next and preserves the type bits.
*
* See additional comments above static_key_set_entries().
*/
static void static_key_set_mod(struct static_key *key,
struct static_key_mod *mod)
{
unsigned long type;
WARN_ON_ONCE((unsigned long)mod & JUMP_TYPE_MASK);
type = key->type & JUMP_TYPE_MASK;
key->next = mod;
key->type |= type;
}
static int __jump_label_mod_text_reserved(void *start, void *end)
{
struct module *mod;
int ret;
scoped_guard(rcu) {
mod = __module_text_address((unsigned long)start);
WARN_ON_ONCE(__module_text_address((unsigned long)end) != mod);
if (!try_module_get(mod))
mod = NULL;
}
if (!mod)
return 0;
ret = __jump_label_text_reserved(mod->jump_entries,
mod->jump_entries + mod->num_jump_entries,
start, end, mod->state == MODULE_STATE_COMING);
module_put(mod);
return ret;
}
static void __jump_label_mod_update(struct static_key *key)
{
struct static_key_mod *mod;
for (mod = static_key_mod(key); mod; mod = mod->next) {
struct jump_entry *stop;
struct module *m;
/*
* NULL if the static_key is defined in a module
* that does not use it
*/
if (!mod->entries)
continue;
m = mod->mod;
if (!m)
stop = __stop___jump_table;
else
stop = m->jump_entries + m->num_jump_entries;
__jump_label_update(key, mod->entries, stop,
m && m->state == MODULE_STATE_COMING);
}
}
static int jump_label_add_module(struct module *mod)
{
struct jump_entry *iter_start = mod->jump_entries;
struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
struct jump_entry *iter;
struct static_key *key = NULL;
struct static_key_mod *jlm, *jlm2;
/* if the module doesn't have jump label entries, just return */
if (iter_start == iter_stop)
return 0;
jump_label_sort_entries(iter_start, iter_stop);
Annotation
- Immediate include surface: `linux/memory.h`, `linux/uaccess.h`, `linux/module.h`, `linux/list.h`, `linux/slab.h`, `linux/sort.h`, `linux/err.h`, `linux/static_key.h`.
- Detected declarations: `struct static_key_mod`, `function jump_label_lock`, `function jump_label_unlock`, `function jump_label_cmp`, `function jump_label_swap`, `function jump_label_sort_entries`, `function static_key_count`, `function static_key_fast_inc_not_disabled`, `function static_key_slow_inc_cpuslocked`, `function static_key_slow_inc`.
- 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.