arch/x86/kernel/cpu/aperfmperf.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/cpu/aperfmperf.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/cpu/aperfmperf.c- Extension
.c- Size
- 14050 bytes
- Lines
- 553
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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/cpufreq.hlinux/delay.hlinux/ktime.hlinux/math64.hlinux/percpu.hlinux/rcupdate.hlinux/sched/isolation.hlinux/sched/topology.hlinux/smp.hlinux/syscore_ops.hasm/cpu.hasm/cpu_device_id.hasm/intel-family.hasm/msr.hcpu.h
Detected Declarations
struct aperfmperfstruct arch_hybrid_cpu_scalefunction init_counter_refsfunction arch_set_max_freq_ratiofunction turbo_disabledfunction slv_set_max_freq_ratiofunction knl_set_max_freq_ratiofunction skx_set_max_freq_ratiofunction core_set_max_freq_ratiofunction intel_set_max_freq_ratiofunction register_freq_invariance_syscorefunction register_freq_invariance_syscorefunction freq_invariance_set_perf_ratiofunction bp_init_freq_invariancefunction disable_freq_invariance_workfnfunction arch_enable_hybrid_capacity_scalefunction for_each_possible_cpufunction arch_set_cpu_capacityfunction arch_scale_cpu_capacityfunction scale_freq_tickfunction bp_init_freq_invariancefunction arch_freq_get_on_cpufunction bp_init_aperfmperffunction ap_init_aperfmperfexport arch_set_max_freq_ratioexport arch_scale_cpu_capacity
Annotated Snippet
struct aperfmperf {
seqcount_t seq;
unsigned long last_update;
u64 acnt;
u64 mcnt;
u64 aperf;
u64 mperf;
};
static DEFINE_PER_CPU_SHARED_ALIGNED(struct aperfmperf, cpu_samples) = {
.seq = SEQCNT_ZERO(cpu_samples.seq)
};
static void init_counter_refs(void *data)
{
u64 aperf, mperf;
rdmsrq(MSR_IA32_APERF, aperf);
rdmsrq(MSR_IA32_MPERF, mperf);
this_cpu_write(cpu_samples.aperf, aperf);
this_cpu_write(cpu_samples.mperf, mperf);
}
#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
/*
* APERF/MPERF frequency ratio computation.
*
* The scheduler wants to do frequency invariant accounting and needs a <1
* ratio to account for the 'current' frequency, corresponding to
* freq_curr / freq_max.
*
* Since the frequency freq_curr on x86 is controlled by micro-controller and
* our P-state setting is little more than a request/hint, we need to observe
* the effective frequency 'BusyMHz', i.e. the average frequency over a time
* interval after discarding idle time. This is given by:
*
* BusyMHz = delta_APERF / delta_MPERF * freq_base
*
* where freq_base is the max non-turbo P-state.
*
* The freq_max term has to be set to a somewhat arbitrary value, because we
* can't know which turbo states will be available at a given point in time:
* it all depends on the thermal headroom of the entire package. We set it to
* the turbo level with 4 cores active.
*
* Benchmarks show that's a good compromise between the 1C turbo ratio
* (freq_curr/freq_max would rarely reach 1) and something close to freq_base,
* which would ignore the entire turbo range (a conspicuous part, making
* freq_curr/freq_max always maxed out).
*
* An exception to the heuristic above is the Atom uarch, where we choose the
* highest turbo level for freq_max since Atom's are generally oriented towards
* power efficiency.
*
* Setting freq_max to anything less than the 1C turbo ratio makes the ratio
* freq_curr / freq_max to eventually grow >1, in which case we clip it to 1.
*/
DEFINE_STATIC_KEY_FALSE(arch_scale_freq_key);
static u64 arch_turbo_freq_ratio = SCHED_CAPACITY_SCALE;
static u64 arch_max_freq_ratio = SCHED_CAPACITY_SCALE;
void arch_set_max_freq_ratio(bool turbo_disabled)
{
arch_max_freq_ratio = turbo_disabled ? SCHED_CAPACITY_SCALE :
arch_turbo_freq_ratio;
}
EXPORT_SYMBOL_GPL(arch_set_max_freq_ratio);
static bool __init turbo_disabled(void)
{
u64 misc_en;
int err;
err = rdmsrq_safe(MSR_IA32_MISC_ENABLE, &misc_en);
if (err)
return false;
return (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
}
static bool __init slv_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq)
{
int err;
err = rdmsrq_safe(MSR_ATOM_CORE_RATIOS, base_freq);
if (err)
return false;
Annotation
- Immediate include surface: `linux/cpufreq.h`, `linux/delay.h`, `linux/ktime.h`, `linux/math64.h`, `linux/percpu.h`, `linux/rcupdate.h`, `linux/sched/isolation.h`, `linux/sched/topology.h`.
- Detected declarations: `struct aperfmperf`, `struct arch_hybrid_cpu_scale`, `function init_counter_refs`, `function arch_set_max_freq_ratio`, `function turbo_disabled`, `function slv_set_max_freq_ratio`, `function knl_set_max_freq_ratio`, `function skx_set_max_freq_ratio`, `function core_set_max_freq_ratio`, `function intel_set_max_freq_ratio`.
- Atlas domain: Architecture Layer / arch/x86.
- 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.