drivers/cpuidle/governors/ladder.c
Source file repositories/reference/linux-study-clean/drivers/cpuidle/governors/ladder.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cpuidle/governors/ladder.c- Extension
.c- Size
- 5340 bytes
- Lines
- 199
- Domain
- Driver Families
- Bucket
- drivers/cpuidle
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/cpuidle.hlinux/jiffies.hlinux/tick.hasm/io.hlinux/uaccess.h
Detected Declarations
struct ladder_device_statestruct ladder_devicefunction ladder_do_selectionfunction ladder_select_statefunction ladder_enable_devicefunction ladder_reflectfunction init_ladder
Annotated Snippet
struct ladder_device_state {
struct {
u32 promotion_count;
u32 demotion_count;
u64 promotion_time_ns;
u64 demotion_time_ns;
} threshold;
struct {
int promotion_count;
int demotion_count;
} stats;
};
struct ladder_device {
struct ladder_device_state states[CPUIDLE_STATE_MAX];
};
static DEFINE_PER_CPU(struct ladder_device, ladder_devices);
/**
* ladder_do_selection - prepares private data for a state change
* @dev: the CPU
* @ldev: the ladder device
* @old_idx: the current state index
* @new_idx: the new target state index
*/
static inline void ladder_do_selection(struct cpuidle_device *dev,
struct ladder_device *ldev,
int old_idx, int new_idx)
{
ldev->states[old_idx].stats.promotion_count = 0;
ldev->states[old_idx].stats.demotion_count = 0;
dev->last_state_idx = new_idx;
}
/**
* ladder_select_state - selects the next state to enter
* @drv: cpuidle driver
* @dev: the CPU
* @dummy: not used
*/
static int ladder_select_state(struct cpuidle_driver *drv,
struct cpuidle_device *dev, bool *dummy)
{
struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
struct ladder_device_state *last_state;
int last_idx = dev->last_state_idx;
int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
s64 latency_req = cpuidle_governor_latency_req(dev->cpu);
s64 last_residency;
/* Special case when user has set very strict latency requirement */
if (unlikely(latency_req == 0)) {
ladder_do_selection(dev, ldev, last_idx, 0);
return 0;
}
last_state = &ldev->states[last_idx];
last_residency = dev->last_residency_ns - drv->states[last_idx].exit_latency_ns;
/* consider promotion */
if (last_idx < drv->state_count - 1 &&
!dev->states_usage[last_idx + 1].disable &&
last_residency > last_state->threshold.promotion_time_ns &&
drv->states[last_idx + 1].exit_latency_ns <= latency_req) {
last_state->stats.promotion_count++;
last_state->stats.demotion_count = 0;
if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
ladder_do_selection(dev, ldev, last_idx, last_idx + 1);
return last_idx + 1;
}
}
/* consider demotion */
if (last_idx > first_idx &&
(dev->states_usage[last_idx].disable ||
drv->states[last_idx].exit_latency_ns > latency_req)) {
int i;
for (i = last_idx - 1; i > first_idx; i--) {
if (drv->states[i].exit_latency_ns <= latency_req)
break;
}
ladder_do_selection(dev, ldev, last_idx, i);
return i;
}
if (last_idx > first_idx &&
last_residency < last_state->threshold.demotion_time_ns) {
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/cpuidle.h`, `linux/jiffies.h`, `linux/tick.h`, `asm/io.h`, `linux/uaccess.h`.
- Detected declarations: `struct ladder_device_state`, `struct ladder_device`, `function ladder_do_selection`, `function ladder_select_state`, `function ladder_enable_device`, `function ladder_reflect`, `function init_ladder`.
- Atlas domain: Driver Families / drivers/cpuidle.
- 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.