lib/once.c
Source file repositories/reference/linux-study-clean/lib/once.c
File Facts
- System
- Linux kernel
- Corpus path
lib/once.c- Extension
.c- Size
- 2269 bytes
- Lines
- 99
- 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/slab.hlinux/spinlock.hlinux/once.hlinux/random.hlinux/module.h
Detected Declarations
struct once_workfunction once_deferredfunction once_disable_jumpfunction __do_once_startfunction __do_once_donefunction __do_once_sleepable_startfunction __do_once_sleepable_doneexport __do_once_startexport __do_once_doneexport __do_once_sleepable_startexport __do_once_sleepable_done
Annotated Snippet
struct once_work {
struct work_struct work;
struct static_key_true *key;
struct module *module;
};
static void once_deferred(struct work_struct *w)
{
struct once_work *work;
work = container_of(w, struct once_work, work);
BUG_ON(!static_key_enabled(work->key));
static_branch_disable(work->key);
module_put(work->module);
kfree(work);
}
static void once_disable_jump(struct static_key_true *key, struct module *mod)
{
struct once_work *w;
w = kmalloc_obj(*w, GFP_ATOMIC);
if (!w)
return;
INIT_WORK(&w->work, once_deferred);
w->key = key;
w->module = mod;
__module_get(mod);
schedule_work(&w->work);
}
static DEFINE_SPINLOCK(once_lock);
bool __do_once_start(bool *done, unsigned long *flags)
__acquires(once_lock)
{
spin_lock_irqsave(&once_lock, *flags);
if (*done) {
spin_unlock_irqrestore(&once_lock, *flags);
/* Keep sparse happy by restoring an even lock count on
* this lock. In case we return here, we don't call into
* __do_once_done but return early in the DO_ONCE() macro.
*/
__acquire(once_lock);
return false;
}
return true;
}
EXPORT_SYMBOL(__do_once_start);
void __do_once_done(bool *done, struct static_key_true *once_key,
unsigned long *flags, struct module *mod)
__releases(once_lock)
{
*done = true;
spin_unlock_irqrestore(&once_lock, *flags);
once_disable_jump(once_key, mod);
}
EXPORT_SYMBOL(__do_once_done);
static DEFINE_MUTEX(once_mutex);
bool __do_once_sleepable_start(bool *done)
__acquires(once_mutex)
{
mutex_lock(&once_mutex);
if (*done) {
mutex_unlock(&once_mutex);
/* Keep sparse happy by restoring an even lock count on
* this mutex. In case we return here, we don't call into
* __do_once_done but return early in the DO_ONCE_SLEEPABLE() macro.
*/
__acquire(once_mutex);
return false;
}
return true;
}
EXPORT_SYMBOL(__do_once_sleepable_start);
void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
struct module *mod)
__releases(once_mutex)
{
*done = true;
mutex_unlock(&once_mutex);
static_branch_disable(once_key);
}
Annotation
- Immediate include surface: `linux/slab.h`, `linux/spinlock.h`, `linux/once.h`, `linux/random.h`, `linux/module.h`.
- Detected declarations: `struct once_work`, `function once_deferred`, `function once_disable_jump`, `function __do_once_start`, `function __do_once_done`, `function __do_once_sleepable_start`, `function __do_once_sleepable_done`, `export __do_once_start`, `export __do_once_done`, `export __do_once_sleepable_start`.
- 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.