The Linux timer interrupt handler doesn’t do all that much directly. For x86, you’ll find the default PIT/HPET timer interrupt handler in arch/x86/kernel/time.c:

static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
    global_clock_event->event_handler(global_clock_event);
    return IRQ_HANDLED;
}

This calls the event handler for global clock events, tick_handler_periodic by default, which updates the jiffies counter, calculates the global load, and updates a few other places where time is tracked.

As a side-effect of an interrupt occurring, __schedule might end up being called, so a timer interrupt can also lead to a task switch (like any other interrupt).

Changing CONFIG_HZ changes the timer interrupt’s periodicity. Increasing HZ means that it fires more often, so there’s more timer-related overhead, but less opportunity for task scheduling to wait for a while (so interactivity is improved); decreasing HZ means that it fires less often, so there’s less timer-related overhead, but a higher risk that tasks will wait to be scheduled (so throughput is improved at the expense of interactive responsiveness). As always, the best compromise depends on your specific workload. Nowadays CONFIG_HZ is less relevant for scheduling aspects anyway; see How to change the length of time-slices used by the Linux CPU scheduler?

See also How is an Interrupt handled in Linux?

Answer from Stephen Kitt on Stack Exchange
Top answer
1 of 2
14

The Linux timer interrupt handler doesn’t do all that much directly. For x86, you’ll find the default PIT/HPET timer interrupt handler in arch/x86/kernel/time.c:

static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
    global_clock_event->event_handler(global_clock_event);
    return IRQ_HANDLED;
}

This calls the event handler for global clock events, tick_handler_periodic by default, which updates the jiffies counter, calculates the global load, and updates a few other places where time is tracked.

As a side-effect of an interrupt occurring, __schedule might end up being called, so a timer interrupt can also lead to a task switch (like any other interrupt).

Changing CONFIG_HZ changes the timer interrupt’s periodicity. Increasing HZ means that it fires more often, so there’s more timer-related overhead, but less opportunity for task scheduling to wait for a while (so interactivity is improved); decreasing HZ means that it fires less often, so there’s less timer-related overhead, but a higher risk that tasks will wait to be scheduled (so throughput is improved at the expense of interactive responsiveness). As always, the best compromise depends on your specific workload. Nowadays CONFIG_HZ is less relevant for scheduling aspects anyway; see How to change the length of time-slices used by the Linux CPU scheduler?

See also How is an Interrupt handled in Linux?

2 of 2
1

what Linux does in the timer interrupt?

I take this as asking for the in-between actions.

I copy from that __schedule():

 *   3. Wakeups don't really cause entry into schedule(). They add a
 *      task to the run-queue and that's it.
 *
 *      Now, if the new task added to the run-queue preempts the current
 *      task, then the wakeup sets TIF_NEED_RESCHED and schedule() gets
 *      called on the nearest possible occasion:

This is a good starting point; it is well documented. This is the start of a long story. What is a "wakeup"? Is it about R and S states? and blocking?

I have only one slight objection to S.K.'s answer, and to one of the links: about HZ being "not so important anymore".

Can be because there was some confusion in the past, some overcorrection from 100HZ to 1000HZ then back to 300HZ, so to fit "multimedia" at the same time (think of HPET origin 2005: "multimedia timer").

Can be with 4 and more cores it also matters less. But depending on what you want to do with your "server" it still should matter - this latency / throughput trade-off can be important under heavy load.

And if the scheduling is not done in the timer interrupts, then it is done in these "other" interrupts.

And why is HZ not configurable (boot or even runtime)?

🌐
Reddit
reddit.com › r/linux › how does the interrupt timer frequency affect latency/throughput?
r/linux on Reddit: How does the interrupt timer frequency affect latency/throughput?
April 8, 2024 -

I've poked around on the internet quite a bit but I've found very little information. Supposedly (as of over 10 years ago according to the few threads I've found) the scheduler is triggered every time the interrupt timer fires, which implies that adjusting the timer frequency changes the scheduler timeslice. Shouldn't that have an impact on latency/throughput? If that's the case:

  1. Why is it only settable at compile time? The kernel gained support for setting the preemption model at boottime and at runtime a while ago. Is the difference from changing the interrupt timer frequency that negligible that no one has bothered making it at least make it settable on the kernel command line even with a non-upstreamed patch? Is there some other technical reason? I have no idea if hardware supports changing it at runtime.

  2. Different distros set it to a different value. How much does this change influence their performance in different scenarios? To name a few, Debian and Ubuntu use 250Hz, Arch uses 300Hz, and Fedora and Void use 1000Hz. Of note, the XanMod kernel packaged for Debian/Ubuntu keeps the default 250Hz, which is interesting if aiming for the best latency.

As far as I've looked, no one has done comprehensive benchmarks on the effect of changing the interrupt timer frequency. Does anyone know of any?

🌐
Medium
medium.com › @satya.devicedriver › the-use-of-timers-in-linux-drivers-419662ad2f2d
The use of Timers in Linux drivers ? | by Satya Prakash | Medium
December 6, 2023 - #LinuxHZ : > The Linux kernel issues a timer interrupt (IRQ 0) every fixed period. HZ is used to define how many timer interrupts there are per second. For example Say, HZ is 1000, which means there are 1000 timer interrupts per second.
🌐
Codefinity
codefinity.com › courses › v2 › d2508ed4-bbc6-406b-b4a1-ba4945da1862 › b989319f-9aa9-4534-84fb-14cab3c80b69 › a5d3d6a5-2c17-44bf-b92f-f24b5fe95857
Learn Timers and Deferred Work | Interrupts, Timing, and Concurrency
Both mechanisms help you keep interrupt handlers fast and responsive by moving time-consuming or blocking operations outside the critical interrupt path. ... 1234567891011121314151617181920212223242526272829303132 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/timer.h> static struct timer_list my_timer; void timer_callback(struct timer_list *timer) { pr_info("Timer callback function called.\n"); } static int __init timer_init(void) { pr_info("Initializing timer example module.\n"); timer_setup(&my_timer, timer_callback, 0); mod_timer(&my_timer, jiff
🌐
Umass
lass.cs.umass.edu › ~shenoy › courses › spring20 › lectures › Lec20.pdf pdf
Linux Kernel Synchronization and Timers Ahmed Ali-Eldin
is no work for 50ms, the kernel reschedules the interrupt to go off in 50ms. ... With a tick rate of 100, a 32-bit jiffies variable would overflow in about 497 days. ... This is important for long running servers! ... RTC running and the BIOS settings preserved. ... On x86, the primary system timer is the programmable interrupt timer (PIT).
Top answer
1 of 4
13

The local timer interrupt is a timer implemented on the APIC that interrupts only a particular CPU instead of raising an interrupt that can be handled by any CPU. It's discussed in Bovet & Cesati's "Understanding the Linux Kernel". A snippet:

The local APIC present in recent 80x86 microprocessors (see the section “Interrupts and Exceptions” in Chapter 4) provides yet another time-measuring device: the CPU local timer.

The CPU local timer is a device similar to the Programmable Interval Timer (PIT) just described that can issue one-shot or periodic interrupts. There are, however, a few differences:

  • The APIC’s timer counter is 32 bits long, while the PIT’s timer counter is 16 bits long; therefore, the local timer can be programmed to issue interrupts at very low frequencies (the counter stores the number of ticks that must elapse before the interrupt is issued).
  • The local APIC timer sends an interrupt only to its processor, while the PIT raises a global interrupt, which may be handled by any CPU in the system.
  • The APIC’s timer is based on the bus clock signal (or the APIC bus signal, in older machines). It can be programmed in such a way to decrease the timer counter every 1, 2, 4, 8, 16, 32, 64, or 128 bus clock signals. Conversely, the PIT, which makes use of its own clock signals, can be programmed in a more flexible way.
2 of 4
10

A less technical answer than Michael Burr's:

Some things need to be done every jiffy, and it doesn't matter on which CPU.
Other things need to be done every jiffy on each CPU. For example, checking if we need to switch to another process.

The local timer interrupt exists for the second type. Whenever it's executed, we check them and do what's needed.

🌐
GitHub
github.com › wbthomason › rustKernelTimer
GitHub - wbthomason/rustKernelTimer: A simple and ugly kernel timer for *nix systems, implemented in Rust. · GitHub
A simple and ugly kernel timer for *nix systems, implemented in Rust. - wbthomason/rustKernelTimer
Author   wbthomason
Find elsewhere
🌐
EmbeTronicX
embetronicx.com › tutorials › linux › device-drivers › using-kernel-timer-in-linux-device-driver
Using Kernel Timer In Linux Device Driver – Linux Device Driver Tutorial Part 26
September 16, 2023 - These timers are used to schedule the execution of a function at a particular time in the future, based on the clock tick, and can be used for a variety of tasks. Polling a device by checking its state at regular intervals when the hardware ...
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › programming › bare metal, assembly language
Using the system timer interrupt at 1MHz - Raspberry Pi Forums
But the question was, how to use one of the channels of the system timer. I am hoping someone has experience on how to change the interrupt table and connecting an interrupt routine to it. It really should be possible to have something simple as toggling a gpio in that routine, and then I can start from there. I will also take a look at the CPU documentation to find out about it. Thanks again, Sietse ... The baremetal version for generating the IRQ is about 10 post back. In linux you are wasting your time it isn't possible because linux has it own needs for the IRQ system and on the Raspberry Pi it has heavy interrupt sharing as there is only one IRQ signal.
🌐
Linux Inside
0xax.gitbooks.io › linux-insides › content › Timers › linux-timers-1.html
Timers and time management in the Linux kernel. Part 1. - 0xax
The main point of the clocksource is timekeeping abstraction or in very simple words - it provides a time value to the kernel. We already know about the jiffies interface that represents number of ticks that have occurred since the system booted. It is represented by a global variable in the Linux kernel and increases each timer interrupt.
🌐
Unix Community
community.unix.com › unix for beginners q & a › unix for dummies questions & answers
timer interrupt - UNIX for Dummies Questions & Answers - Unix Linux Community
June 18, 2006 - hello all since a process running in kernel mode cannnot be preempted by any other process what would be the status of Timer interrupt that occurs when the time quantum of a process is elapsed? thanks
🌐
STMicroelectronics Community
community.st.com › stmicroelectronics community › discussions › product forums › stm32 mpus › stm32 mpus embedded software and solutions › how can i generate a periodic signal on a gpio using timer interrupt in linux kernel (stm32mp153a)?
How can I generate a periodic signal on a GPIO using timer interrupt in Linux kernel (STM32MP153a)? | Community
June 8, 2022 - At hardware level it is supported and the register UIF is raised, but there is no mechanism at driver level that throw an interrupt. This feature of doing a periodic timer can be done easily by software, which avoid to clock the hardware. ... This link show how to do a periodic timer in a linux driver with an handler.
🌐
LinuxQuestions.org
linuxquestions.org › questions › linux-general-1 › one-question-about-local-timer-interrupt-on-tickless-system-912914
one question about local timer interrupt on tickless system
November 10, 2011 - hi all, I'm having a 2.6.34 tickless kernel on my machine and i disabled the irq balance and isolcpu1-7. So the core1-7 are at idle state. One thing i
🌐
Bootlin
bootlin.com › blog › timer-counters-linux-microchip
Practical usage of timer counters in Linux, illustrated on Microchip platforms – Bootlin
Also please make sure you are using a kernel with the following patch applied: https://github.com/torvalds/linux/commit/061f8572a31c0da6621aacfc70ed16e1a6d1d33b ... Hi I have configured the tcb like this —————————————– tcb: timer@f8008000 { compatible = “atmel,sama5d2-tcb”, “simple-mfd”, “syscon”; reg = ; #address-cells = ; #size-cells = ; interrupts = ; clocks = , ; clock-names = “t0_clk”, “slow_clk”; assigned-clocks = ; assigned-clock-rates = ; assigned-clock-parents = ; status = “disabled”; }; —————————————– tim
🌐
O'Reilly
oreilly.com › library › view › understanding-the-linux › 0596005652 › ch04s06.html
4.6. Interrupt Handling - Understanding the Linux Kernel, 3rd Edition [Book]
November 17, 2005 - We cover this type of interrupt in the later section "I/O Interrupt Handling.” ... Some timer, either a local APIC timer or an external timer, has issued an interrupt; this kind of interrupt tells the kernel that a fixed-time interval has elapsed.
Authors   Daniel P. BovetMarco Cesati
Published   2005
Pages   942
🌐
Kit
telematics.tm.kit.edu › publications › Files › 61 › walter_ibm_linux_challenge.pdf pdf
µ-second precision timer support for the Linux kernel
controller (PIC 8259A) which offers the possibility to generate interrupts with a configurable frequency. The · Linux kernel uses this periodical moments of time to schedule and execute timer functions.
🌐
Endless Learning
hyeyoo.com › 90
[Linux Kernel] 시간과 타이머
May 5, 2021 - * * @TIMER_IRQSAFE: An irqsafe timer is executed with IRQ disabled and * it's safe to wait for the completion of the running instance from * IRQ handlers, for example, by calling del_timer_sync(). * * Note: The irq disabled callback execution is a special case for * workqueue locking issues. It's not meant for executing random crap * with interrupts disabled.
🌐
Linux Kernel
docs.kernel.org › timers › no_hz.html
NO_HZ: Reducing Scheduling-Clock Ticks — The Linux Kernel documentation
The CONFIG_NO_HZ_IDLE=y Kconfig option causes the kernel to avoid sending scheduling-clock interrupts to idle CPUs, which is critically important both to battery-powered devices and to highly virtualized mainframes. A battery-powered device running a CONFIG_HZ_PERIODIC=y kernel would drain its battery very quickly, easily 2-3 times as fast as would the same device running a CONFIG_NO_HZ_IDLE=y kernel.
🌐
Uniroma2
ce.uniroma2.it › ~pellegrini › › didattica › 2018 › aosv › 11.Interrupt-Management.pdf pdf
Alessandropellegrini
I’m an Associate Professor in the Department of Civil Engineering and Computer Science Engineering (DICII) at University of Rome “Tor Vergata”, head of the High Performance Computing and Simulation research group · I am also an associate of the Institute of Systems Analysis and Informatics ...