arch/x86/kernel/tsc.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/tsc.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/tsc.c- Extension
.c- Size
- 41716 bytes
- Lines
- 1597
- 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/kernel.hlinux/sched.hlinux/sched/clock.hlinux/init.hlinux/export.hlinux/timer.hlinux/acpi_pmtmr.hlinux/cpufreq.hlinux/delay.hlinux/clocksource.hlinux/kvm_types.hlinux/percpu.hlinux/timex.hlinux/static_key.hlinux/static_call.hasm/cpuid/api.hasm/hpet.hasm/timer.hasm/vgtod.hasm/time.hasm/delay.hasm/hypervisor.hasm/nmi.hasm/x86_init.hasm/geode.hasm/apic.hasm/cpu_device_id.hasm/i8259.hasm/msr.hasm/topology.hasm/uv/uv.hasm/sev.h
Detected Declarations
struct cyc2nsfunction tsc_early_khz_setupfunction __cyc2ns_readfunction cyc2ns_read_beginfunction cyc2ns_read_endfunction sched_clockfunction cycles_2_nsfunction __set_cyc2ns_scalefunction arch_perf_update_userpagefunction set_cyc2ns_scalefunction cyc2ns_init_boot_cpufunction tsc_initfunction for_each_possible_cpufunction native_sched_clockfunction native_sched_clock_from_tscfunction sched_clock_noinstrfunction using_native_sched_clockfunction paravirt_set_sched_clockfunction using_native_sched_clockfunction paravirt_set_sched_clockfunction check_tsc_unstablefunction notsc_setupfunction tsc_setupfunction tsc_read_refsfunction calc_hpet_reffunction calc_pmtimer_reffunction pit_calibrate_tscfunction fasterfunction pit_expect_msbfunction quick_pit_calibratefunction native_calibrate_tscfunction cpu_khz_from_cpuidfunction pit_hpet_ptimer_calibrate_cpufunction native_calibrate_cpu_earlyfunction native_calibrate_cpufunction recalibrate_cpu_khzfunction tsc_save_sched_clock_statefunction valuefunction for_each_possible_cpufunction time_cpufreq_notifierfunction cpufreq_register_tsc_scalingfunction detect_artfunction tsc_resumefunction read_tscfunction tsc_cs_mark_unstablefunction tsc_cs_tick_stablefunction tsc_cs_enablefunction mark_tsc_unstable
Annotated Snippet
core_initcall(cpufreq_register_tsc_scaling);
#endif /* CONFIG_CPU_FREQ */
#define ART_MIN_DENOMINATOR (1)
/*
* If ART is present detect the numerator:denominator to convert to TSC
*/
static void __init detect_art(void)
{
unsigned int unused;
if (boot_cpu_data.cpuid_level < CPUID_LEAF_TSC)
return;
/*
* Don't enable ART in a VM, non-stop TSC and TSC_ADJUST required,
* and the TSC counter resets must not occur asynchronously.
*/
if (boot_cpu_has(X86_FEATURE_HYPERVISOR) ||
!boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ||
!boot_cpu_has(X86_FEATURE_TSC_ADJUST) ||
tsc_async_resets)
return;
cpuid(CPUID_LEAF_TSC, &art_base_clk.denominator,
&art_base_clk.numerator, &art_base_clk.freq_khz, &unused);
art_base_clk.freq_khz /= KHZ;
if (art_base_clk.denominator < ART_MIN_DENOMINATOR)
return;
rdmsrq(MSR_IA32_TSC_ADJUST, art_base_clk.offset);
/* Make this sticky over multiple CPU init calls */
setup_force_cpu_cap(X86_FEATURE_ART);
}
/* clocksource code */
static void tsc_resume(struct clocksource *cs)
{
tsc_verify_tsc_adjust(true);
}
/*
* We used to compare the TSC to the cycle_last value in the clocksource
* structure to avoid a nasty time-warp. This can be observed in a
* very small window right after one CPU updated cycle_last under
* xtime/vsyscall_gtod lock and the other CPU reads a TSC value which
* is smaller than the cycle_last reference value due to a TSC which
* is slightly behind. This delta is nowhere else observable, but in
* that case it results in a forward time jump in the range of hours
* due to the unsigned delta calculation of the time keeping core
* code, which is necessary to support wrapping clocksources like pm
* timer.
*
* This sanity check is now done in the core timekeeping code.
* checking the result of read_tsc() - cycle_last for being negative.
* That works because CLOCKSOURCE_MASK(64) does not mask out any bit.
*/
static u64 read_tsc(struct clocksource *cs)
{
return (u64)rdtsc_ordered();
}
static void tsc_cs_mark_unstable(struct clocksource *cs)
{
if (tsc_unstable)
return;
tsc_unstable = 1;
if (using_native_sched_clock())
clear_sched_clock_stable();
pr_info("Marking TSC unstable due to clocksource watchdog\n");
}
static void tsc_cs_tick_stable(struct clocksource *cs)
{
if (tsc_unstable)
return;
if (using_native_sched_clock())
sched_clock_tick_stable();
}
static int tsc_cs_enable(struct clocksource *cs)
{
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched.h`, `linux/sched/clock.h`, `linux/init.h`, `linux/export.h`, `linux/timer.h`, `linux/acpi_pmtmr.h`, `linux/cpufreq.h`.
- Detected declarations: `struct cyc2ns`, `function tsc_early_khz_setup`, `function __cyc2ns_read`, `function cyc2ns_read_begin`, `function cyc2ns_read_end`, `function sched_clock`, `function cycles_2_ns`, `function __set_cyc2ns_scale`, `function arch_perf_update_userpage`, `function set_cyc2ns_scale`.
- 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.