include/linux/trace_recursion.h
Source file repositories/reference/linux-study-clean/include/linux/trace_recursion.h
File Facts
- System
- Linux kernel
- Corpus path
include/linux/trace_recursion.h- Extension
.h- Size
- 5375 bytes
- Lines
- 199
- Domain
- Core OS
- Bucket
- Core Kernel Interface
- 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.
Dependency Surface
linux/interrupt.hlinux/sched.h
Detected Declarations
function trace_get_context_bitfunction trace_test_and_set_recursionfunction enabledfunction contextfunction ftrace_test_recursion_unlock
Annotated Snippet
if (!trace_recursion_test(TRACE_RECORD_RECURSION_BIT)) { \
trace_recursion_set(TRACE_RECORD_RECURSION_BIT); \
ftrace_record_recursion(ip, pip); \
trace_recursion_clear(TRACE_RECORD_RECURSION_BIT); \
} \
} while (0)
#else
# define do_ftrace_record_recursion(ip, pip) do { } while (0)
#endif
#ifdef CONFIG_FTRACE_VALIDATE_RCU_IS_WATCHING
# define trace_warn_on_no_rcu(ip) \
({ \
bool __ret = !rcu_is_watching(); \
if (__ret && !trace_recursion_test(TRACE_RECORD_RECURSION_BIT)) { \
trace_recursion_set(TRACE_RECORD_RECURSION_BIT); \
WARN_ONCE(true, "RCU not on for: %pS\n", (void *)ip); \
trace_recursion_clear(TRACE_RECORD_RECURSION_BIT); \
} \
__ret; \
})
#else
# define trace_warn_on_no_rcu(ip) false
#endif
/*
* Preemption is promised to be disabled when return bit >= 0.
*/
static __always_inline int trace_test_and_set_recursion(unsigned long ip, unsigned long pip,
int start)
{
unsigned int val = READ_ONCE(current->trace_recursion);
int bit;
if (trace_warn_on_no_rcu(ip))
return -1;
bit = trace_get_context_bit() + start;
if (unlikely(val & (1 << bit))) {
/*
* If an interrupt occurs during a trace, and another trace
* happens in that interrupt but before the preempt_count is
* updated to reflect the new interrupt context, then this
* will think a recursion occurred, and the event will be dropped.
* Let a single instance happen via the TRANSITION_BIT to
* not drop those events.
*/
bit = TRACE_CTX_TRANSITION + start;
if (val & (1 << bit)) {
do_ftrace_record_recursion(ip, pip);
return -1;
}
}
val |= 1 << bit;
current->trace_recursion = val;
barrier();
preempt_disable_notrace();
return bit;
}
/*
* Preemption will be enabled (if it was previously enabled).
*/
static __always_inline void trace_clear_recursion(int bit)
{
preempt_enable_notrace();
barrier();
trace_recursion_clear(bit);
}
/**
* ftrace_test_recursion_trylock - tests for recursion in same context
*
* Use this for ftrace callbacks. This will detect if the function
* tracing recursed in the same context (normal vs interrupt),
*
* Returns: -1 if a recursion happened.
* >= 0 if no recursion.
*/
static __always_inline int ftrace_test_recursion_trylock(unsigned long ip,
unsigned long parent_ip)
{
return trace_test_and_set_recursion(ip, parent_ip, TRACE_FTRACE_START);
}
/**
* ftrace_test_recursion_unlock - called when function callback is complete
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/sched.h`.
- Detected declarations: `function trace_get_context_bit`, `function trace_test_and_set_recursion`, `function enabled`, `function context`, `function ftrace_test_recursion_unlock`.
- Atlas domain: Core OS / Core Kernel Interface.
- Implementation status: source implementation candidate.
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.