Re: [PATCH 05/23] tick: Pass timer tick job to an online HK CPU in tick_cpu_dying()

Waiman Long
2026-04-21T14:22:20Z

On 4/21/26 4:55 AM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>> In tick_cpu_dying(), if the dying CPU is the current timekeeper,
>> it has to pass the job over to another CPU. The current code passes
>> it to another online CPU. However, that CPU may not be a timer tick
>> housekeeping CPU. If that happens, another CPU will have to manually
>> take it over again later. Avoid this unnecessary work by directly
>> assigning an online housekeeping CPU.
>>
>> Use READ_ONCE/WRITE_ONCE() to access tick_do_timer_cpu in case the
>> non-HK CPUs may not be in stop machine in the future.
> 'may not be in the future' is yet more handwaving without
> content. Please write your change logs in a way so that people who have
> not spent months on this can follow.
>
>> @@ -394,12 +395,19 @@ int tick_cpu_dying(unsigned int dying_cpu)
>> {
>> /*
>> * If the current CPU is the timekeeper, it's the only one that can
>> - * safely hand over its duty. Also all online CPUs are in stop
>> - * machine, guaranteed not to be idle, therefore there is no
>> + * safely hand over its duty. Also all online housekeeping CPUs are
>> + * in stop machine, guaranteed not to be idle, therefore there is no
>> * concurrency and it's safe to pick any online successor.
>> */
>> - if (tick_do_timer_cpu == dying_cpu)
>> - tick_do_timer_cpu = cpumask_first(cpu_online_mask);
>> + if (READ_ONCE(tick_do_timer_cpu) == dying_cpu) {
>> + unsigned int new_cpu;
>> +
>> + guard(rcu)();
> What's this guard for?
>
>> + new_cpu = cpumask_first_and(cpu_online_mask, housekeeping_cpumask(HK_TYPE_TICK));
> Why has this to use housekeeping_cpumask() and does not use
> tick_nohz_full_mask?

The RCU guard is for accessing the HK_TYPE_TICK(HK_TYPE_KERNEL_NOISE)
cpumask. tick_nohz_full_mask cpumask is actually the inverse of
HK_TYPE_TICK cpumask. Yes, I could use cpumask_first_andnot() with
tick_nohz_full_mask. If we make tick_nohz_full_mask an RCU protected
pointer, we still need the guard.

Cheers,
Longman