include/kunit/run-in-irq-context.h
Source file repositories/reference/linux-study-clean/include/kunit/run-in-irq-context.h
File Facts
- System
- Linux kernel
- Corpus path
include/kunit/run-in-irq-context.h- Extension
.h- Size
- 5874 bytes
- Lines
- 155
- Domain
- Repository Root And Misc
- Bucket
- include
- Inferred role
- Repository Root And Misc: implementation source
- Status
- source implementation candidate
Why This File Exists
Top-level or miscellaneous repository surface. Use this as map coverage unless a later manual pass promotes the file into a deeper subsystem dossier.
- Top-level or miscellaneous repository surface. Use this as map coverage unless a later manual pass promotes the file into a deeper subsystem dossier.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
kunit/test.hlinux/timekeeping.hlinux/hrtimer.hlinux/workqueue.h
Detected Declarations
struct kunit_irq_test_statefunction kunit_irq_test_timer_funcfunction kunit_irq_test_bh_work_funcfunction irq_fpu_usable
Annotated Snippet
struct kunit_irq_test_state {
bool (*func)(void *test_specific_state);
void *test_specific_state;
bool task_func_reported_failure;
bool hardirq_func_reported_failure;
bool softirq_func_reported_failure;
atomic_t task_func_calls;
atomic_t hardirq_func_calls;
atomic_t softirq_func_calls;
ktime_t interval;
struct hrtimer timer;
struct work_struct bh_work;
};
static enum hrtimer_restart kunit_irq_test_timer_func(struct hrtimer *timer)
{
struct kunit_irq_test_state *state =
container_of(timer, typeof(*state), timer);
int task_calls, hardirq_calls, softirq_calls;
WARN_ON_ONCE(!in_hardirq());
task_calls = atomic_read(&state->task_func_calls);
hardirq_calls = atomic_inc_return(&state->hardirq_func_calls);
softirq_calls = atomic_read(&state->softirq_func_calls);
/*
* If the timer is firing too often for the softirq or task to ever have
* a chance to run, increase the timer interval. This is needed on very
* slow systems.
*/
if (hardirq_calls >= 20 && (softirq_calls == 0 || task_calls == 0))
state->interval = ktime_add_ns(state->interval, 250);
if (!state->func(state->test_specific_state))
state->hardirq_func_reported_failure = true;
hrtimer_forward_now(&state->timer, state->interval);
queue_work(system_bh_wq, &state->bh_work);
return HRTIMER_RESTART;
}
static void kunit_irq_test_bh_work_func(struct work_struct *work)
{
struct kunit_irq_test_state *state =
container_of(work, typeof(*state), bh_work);
WARN_ON_ONCE(!in_serving_softirq());
atomic_inc(&state->softirq_func_calls);
if (!state->func(state->test_specific_state))
state->softirq_func_reported_failure = true;
}
/*
* Helper function which repeatedly runs the given @func in task, softirq, and
* hardirq context concurrently, and reports a failure to KUnit if any
* invocation of @func in any context returns false. @func is passed
* @test_specific_state as its argument. At most 3 invocations of @func will
* run concurrently: one in each of task, softirq, and hardirq context. @func
* will continue running until either @max_iterations calls have been made (so
* long as at least one each runs in task, softirq, and hardirq contexts), or
* one second has passed.
*
* The main purpose of this interrupt context testing is to validate fallback
* code paths that run in contexts where the normal code path cannot be used,
* typically due to the FPU or vector registers already being in-use in kernel
* mode. These code paths aren't covered when the test code is executed only by
* the KUnit test runner thread in task context. The reason for the concurrency
* is because merely using hardirq context is not sufficient to reach a fallback
* code path on some architectures; the hardirq actually has to occur while the
* FPU or vector unit was already in-use in kernel mode.
*
* Another purpose of this testing is to detect issues with the architecture's
* irq_fpu_usable() and kernel_fpu_begin/end() or equivalent functions,
* especially in softirq context when the softirq may have interrupted a task
* already using kernel-mode FPU or vector (if the arch didn't prevent that).
* Crypto functions are often executed in softirqs, so this is important.
*/
static inline void kunit_run_irq_test(struct kunit *test, bool (*func)(void *),
int max_iterations,
void *test_specific_state)
{
struct kunit_irq_test_state state = {
.func = func,
.test_specific_state = test_specific_state,
/*
* Start with a 5us timer interval. If the system can't keep
* up, kunit_irq_test_timer_func() will increase it.
*/
.interval = us_to_ktime(5),
Annotation
- Immediate include surface: `kunit/test.h`, `linux/timekeeping.h`, `linux/hrtimer.h`, `linux/workqueue.h`.
- Detected declarations: `struct kunit_irq_test_state`, `function kunit_irq_test_timer_func`, `function kunit_irq_test_bh_work_func`, `function irq_fpu_usable`.
- Atlas domain: Repository Root And Misc / include.
- 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.