kernel/unwind/deferred.c
Source file repositories/reference/linux-study-clean/kernel/unwind/deferred.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/unwind/deferred.c- Extension
.c- Size
- 10061 bytes
- Lines
- 366
- 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.
- 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/sched/task_stack.hlinux/unwind_deferred.hlinux/sched/clock.hlinux/task_work.hlinux/kernel.hlinux/sched.hlinux/sizes.hlinux/slab.hlinux/mm.h
Detected Declarations
function try_assign_cntfunction try_assign_cntfunction unwind_pendingfunction get_cookiefunction contextfunction process_unwind_deferredfunction srcu_read_lock_heldfunction unwind_deferred_task_workfunction unwind_deferred_task_exitfunction unwind_deferred_requestfunction unwind_deferred_cancelfunction unwind_deferred_initfunction unwind_task_initfunction unwind_task_free
Annotated Snippet
srcu_read_lock_held(&unwind_srcu)) {
if (test_bit(work->bit, &bits)) {
work->func(work, &trace, cookie);
if (info->cache)
info->cache->unwind_completed |= BIT(work->bit);
}
}
}
static void unwind_deferred_task_work(struct callback_head *head)
{
process_unwind_deferred(current);
}
void unwind_deferred_task_exit(struct task_struct *task)
{
struct unwind_task_info *info = ¤t->unwind_info;
if (!unwind_pending(info))
return;
process_unwind_deferred(task);
task_work_cancel(task, &info->work);
}
/**
* unwind_deferred_request - Request a user stacktrace on task kernel exit
* @work: Unwind descriptor requesting the trace
* @cookie: The cookie of the first request made for this task
*
* Schedule a user space unwind to be done in task work before exiting the
* kernel.
*
* The returned @cookie output is the generated cookie of the very first
* request for a user space stacktrace for this task since it entered the
* kernel. It can be from a request by any caller of this infrastructure.
* Its value will also be passed to the callback function. It can be
* used to stitch kernel and user stack traces together in post-processing.
*
* It's valid to call this function multiple times for the same @work within
* the same task entry context. Each call will return the same cookie
* while the task hasn't left the kernel. If the callback is not pending
* because it has already been previously called for the same entry context,
* it will be called again with the same stack trace and cookie.
*
* Return: 0 if the callback successfully was queued.
* 1 if the callback is pending or was already executed.
* Negative if there's an error.
* @cookie holds the cookie of the first request by any user
*/
int unwind_deferred_request(struct unwind_work *work, u64 *cookie)
{
struct unwind_task_info *info = ¤t->unwind_info;
int twa_mode = TWA_RESUME;
unsigned long old, bits;
unsigned long bit;
int ret;
*cookie = 0;
if ((current->flags & (PF_KTHREAD | PF_EXITING)) ||
!user_mode(task_pt_regs(current)))
return -EINVAL;
/*
* NMI requires having safe cmpxchg operations.
* Trigger a warning to make it obvious that an architecture
* is using this in NMI when it should not be.
*/
if (in_nmi()) {
if (WARN_ON_ONCE(!CAN_USE_IN_NMI))
return -EINVAL;
twa_mode = TWA_NMI_CURRENT;
}
/* Do not allow cancelled works to request again */
bit = READ_ONCE(work->bit);
if (WARN_ON_ONCE(bit < 0))
return -EINVAL;
/* Only need the mask now */
bit = BIT(bit);
guard(irqsave)();
*cookie = get_cookie(info);
old = atomic_long_read(&info->unwind_mask);
Annotation
- Immediate include surface: `linux/sched/task_stack.h`, `linux/unwind_deferred.h`, `linux/sched/clock.h`, `linux/task_work.h`, `linux/kernel.h`, `linux/sched.h`, `linux/sizes.h`, `linux/slab.h`.
- Detected declarations: `function try_assign_cnt`, `function try_assign_cnt`, `function unwind_pending`, `function get_cookie`, `function context`, `function process_unwind_deferred`, `function srcu_read_lock_held`, `function unwind_deferred_task_work`, `function unwind_deferred_task_exit`, `function unwind_deferred_request`.
- 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.