drivers/powercap/idle_inject.c
Source file repositories/reference/linux-study-clean/drivers/powercap/idle_inject.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/powercap/idle_inject.c- Extension
.c- Size
- 13282 bytes
- Lines
- 421
- Domain
- Driver Families
- Bucket
- drivers/powercap
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/cpu.hlinux/hrtimer.hlinux/kthread.hlinux/sched.hlinux/slab.hlinux/smpboot.hlinux/idle_inject.huapi/linux/sched/types.h
Detected Declarations
struct idle_inject_threadstruct idle_inject_devicefunction idle_inject_wakeupfunction for_each_cpu_andfunction play_idle_precisefunction play_idle_precisefunction idle_inject_set_durationfunction idle_inject_get_durationfunction idle_inject_set_latencyfunction idle_inject_startfunction idle_inject_stopfunction allfunction idle_inject_setupfunction idle_inject_should_runfunction updatefunction for_each_cpufunction idle_inject_unregisterfunction idle_inject_init
Annotated Snippet
struct idle_inject_thread {
struct task_struct *tsk;
int should_run;
};
/**
* struct idle_inject_device - idle injection data
* @timer: idle injection period timer
* @idle_duration_us: duration of CPU idle time to inject
* @run_duration_us: duration of CPU run time to allow
* @latency_us: max allowed latency
* @update: Optional callback deciding whether or not to skip idle
* injection in the given cycle.
* @cpumask: mask of CPUs affected by idle injection
*
* This structure is used to define per instance idle inject device data. Each
* instance has an idle duration, a run duration and mask of CPUs to inject
* idle.
*
* Actual CPU idle time is injected by calling kernel scheduler interface
* play_idle_precise(). There is one optional callback that can be registered
* by calling idle_inject_register_full():
*
* update() - This callback is invoked just before waking up CPUs to inject
* idle. If it returns false, CPUs are not woken up to inject idle in the given
* cycle. It also allows the caller to readjust the idle and run duration by
* calling idle_inject_set_duration() for the next cycle.
*/
struct idle_inject_device {
struct hrtimer timer;
unsigned int idle_duration_us;
unsigned int run_duration_us;
unsigned int latency_us;
bool (*update)(void);
unsigned long cpumask[];
};
static DEFINE_PER_CPU(struct idle_inject_thread, idle_inject_thread);
static DEFINE_PER_CPU(struct idle_inject_device *, idle_inject_device);
/**
* idle_inject_wakeup - Wake up idle injection threads
* @ii_dev: target idle injection device
*
* Every idle injection task associated with the given idle injection device
* and running on an online CPU will be woken up.
*/
static void idle_inject_wakeup(struct idle_inject_device *ii_dev)
{
struct idle_inject_thread *iit;
unsigned int cpu;
for_each_cpu_and(cpu, to_cpumask(ii_dev->cpumask), cpu_online_mask) {
iit = per_cpu_ptr(&idle_inject_thread, cpu);
iit->should_run = 1;
wake_up_process(iit->tsk);
}
}
/**
* idle_inject_timer_fn - idle injection timer function
* @timer: idle injection hrtimer
*
* This function is called when the idle injection timer expires. It wakes up
* idle injection tasks associated with the timer and they, in turn, invoke
* play_idle_precise() to inject a specified amount of CPU idle time.
*
* Return: HRTIMER_RESTART.
*/
static enum hrtimer_restart idle_inject_timer_fn(struct hrtimer *timer)
{
unsigned int duration_us;
struct idle_inject_device *ii_dev =
container_of(timer, struct idle_inject_device, timer);
if (!ii_dev->update || ii_dev->update())
idle_inject_wakeup(ii_dev);
duration_us = READ_ONCE(ii_dev->run_duration_us);
duration_us += READ_ONCE(ii_dev->idle_duration_us);
hrtimer_forward_now(timer, us_to_ktime(duration_us));
return HRTIMER_RESTART;
}
/**
* idle_inject_fn - idle injection work function
* @cpu: the CPU owning the task
*
Annotation
- Immediate include surface: `linux/cpu.h`, `linux/hrtimer.h`, `linux/kthread.h`, `linux/sched.h`, `linux/slab.h`, `linux/smpboot.h`, `linux/idle_inject.h`, `uapi/linux/sched/types.h`.
- Detected declarations: `struct idle_inject_thread`, `struct idle_inject_device`, `function idle_inject_wakeup`, `function for_each_cpu_and`, `function play_idle_precise`, `function play_idle_precise`, `function idle_inject_set_duration`, `function idle_inject_get_duration`, `function idle_inject_set_latency`, `function idle_inject_start`.
- Atlas domain: Driver Families / drivers/powercap.
- Implementation status: integration 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.