arch/x86/lib/delay.c
Source file repositories/reference/linux-study-clean/arch/x86/lib/delay.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/lib/delay.c- Extension
.c- Size
- 5168 bytes
- Lines
- 232
- 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.
Dependency Surface
linux/export.hlinux/sched.hlinux/timex.hlinux/preempt.hlinux/delay.hasm/processor.hasm/delay.hasm/timer.hasm/mwait.hasm/smp.h
Detected Declarations
function delay_loopfunction delay_tscfunction delay_halt_tpausefunction delay_halt_mwaitxfunction delay_haltfunction use_tsc_delayfunction use_tpause_delayfunction use_mwaitx_delayfunction read_current_timerfunction __delayfunction __const_udelayfunction __udelayfunction __ndelayexport __delayexport __const_udelayexport __udelayexport __ndelay
Annotated Snippet
if (unlikely(cpu != smp_processor_id())) {
cycles -= (now - bclock);
cpu = smp_processor_id();
bclock = rdtsc_ordered();
}
}
preempt_enable();
}
/*
* On Intel the TPAUSE instruction waits until any of:
* 1) the TSC counter exceeds the value provided in EDX:EAX
* 2) global timeout in IA32_UMWAIT_CONTROL is exceeded
* 3) an external interrupt occurs
*/
static void delay_halt_tpause(u64 start, u64 cycles)
{
u64 until = start + cycles;
u32 eax, edx;
eax = lower_32_bits(until);
edx = upper_32_bits(until);
/*
* Hard code the deeper (C0.2) sleep state because exit latency is
* small compared to the "microseconds" that usleep() will delay.
*/
__tpause(TPAUSE_C02_STATE, edx, eax);
}
/*
* On some AMD platforms, MWAITX has a configurable 32-bit timer, that
* counts with TSC frequency. The input value is the number of TSC cycles
* to wait. MWAITX will also exit when the timer expires.
*/
static void delay_halt_mwaitx(u64 unused, u64 cycles)
{
u64 delay;
delay = min_t(u64, MWAITX_MAX_WAIT_CYCLES, cycles);
/*
* Use cpu_tss_rw as a cacheline-aligned, seldom accessed per-cpu
* variable as the monitor target.
*/
__monitorx(raw_cpu_ptr(&cpu_tss_rw), 0, 0);
/*
* AMD, like Intel, supports the EAX hint and EAX=0xf means, do not
* enter any deep C-state and we use it here in delay() to minimize
* wakeup latency.
*/
__mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE);
}
/*
* Call a vendor specific function to delay for a given amount of time. Because
* these functions may return earlier than requested, check for actual elapsed
* time and call again until done.
*/
static void delay_halt(u64 __cycles)
{
u64 start, end, cycles = __cycles;
/*
* Timer value of 0 causes MWAITX to wait indefinitely, unless there
* is a store on the memory monitored by MONITORX.
*/
if (!cycles)
return;
start = rdtsc_ordered();
for (;;) {
delay_halt_fn(start, cycles);
end = rdtsc_ordered();
if (cycles <= end - start)
break;
cycles -= end - start;
start = end;
}
}
void __init use_tsc_delay(void)
{
if (delay_fn == delay_loop)
delay_fn = delay_tsc;
}
Annotation
- Immediate include surface: `linux/export.h`, `linux/sched.h`, `linux/timex.h`, `linux/preempt.h`, `linux/delay.h`, `asm/processor.h`, `asm/delay.h`, `asm/timer.h`.
- Detected declarations: `function delay_loop`, `function delay_tsc`, `function delay_halt_tpause`, `function delay_halt_mwaitx`, `function delay_halt`, `function use_tsc_delay`, `function use_tpause_delay`, `function use_mwaitx_delay`, `function read_current_timer`, `function __delay`.
- 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.