'Understanding the `scheduler_tick()` function of Linux Kernel

To my knowledge, I understood that the scheduler_tick() function periodically gets called by the timer interrupt with the frequency of HZ.

I'm new to kernel development, so these might be naive questions but I'm trying to understand the execution of the scheduler_tick() function. I'd appreciate your help on these questions:

  1. It is possible for the timer to invoke this function again before the previous call returns?

  2. Is it called per-core? (with per-core timer interrupt)

  3. If the HZ frequency is high, the scheduler executes a process for longer than its timeslice. If the HZ is low, I presume a significant overhead due to frequent interruptions and invocation of this function. Is this assumption correct?



Solution 1:[1]

Answering your main questions and comments at the same time:

  1. It's not possible for scheduler code to be called while already scheduling, as it runs with interrupts disabled.
  2. Yes, each core has its own runqueue and does its own scheduling.
  3. It's the opposite: high HZ -> scheduler will run more frequently (since HZ represents the number of scheduling ticks per second); low HZ -> scheduler will run less frequently.

Scheduling on every single core simultaneously is not needed, each CPU has its own timer and does its own timer interrupts regardless of sync with other CPUs. Scheduler ticks don't happen at the same time on all CPUs (furthermore CPUs could be idle and not ticking at all in a "tickless" kernel, configured with CONFIG_NOHZ). Tickless kernels make things a bit tricker, for more info check out Documentation/timers/NO_HZ.txt and "How are jiffies incremented in a tickless kernel?".

As per what trigger_load_balance() does and how, see Documentation/scheduler/sched-domains.txt, which explains it more or less in detail. In particular, trigger_load_balance() doesn't do the actual load balancing, it just checks if it's needed and if so raises a soft IRQ (SCHED_SOFTIRQ), which is then handled by run_rebalance_domains(), which calls rebalance_domains(), which does the actual work. The latter function indeed uses RCU/locking, as you can see by the calls to functions such as spin_trylock() and rcu_read_lock().

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1