All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <frederic@kernel.org>
To: Marco Crivellari <marco.crivellari@suse.com>
Cc: linux-kernel@vger.kernel.org,
	"Paul E . McKenney" <paulmck@kernel.org>,
	Ingo Molnar <mingo@kernel.org>, Michal Hocko <mhocko@suse.com>,
	Aaron Tomlin <atomlin@atomlin.com>,
	Anna-Maria Behnsen <anna-maria@linutronix.de>,
	Thomas Gleixner <tglx@kernel.org>
Subject: Re: [PATCH 1/3] tick/nohz: Re-evaluate the tick on polling idle and on user entry
Date: Tue, 10 Nov 2026 14:33:45 +0100	[thread overview]
Message-ID: <avMdOa44c5qvryuH@localhost.localdomain> (raw)
In-Reply-To: <CAAofZF6_JpSDNSKUuePiJx+74tbRH8vJ4spyNGp9KbjFPrbA0w@mail.gmail.com>

Le Mon, Nov 09, 2026 at 06:24:22PM +0100, Marco Crivellari a écrit :
> Mmh I'm not entirely sure. Look at this:
> 
> Without that hunk:
> 
> <idle>-0       [002] dN.1.    21.838685: csd_function_entry:
> func=idle_cycle [nohz_poll_timer_test], csd=0000000006a53f0a
> <idle>-0       [002] dN.2.    21.889256: hrtimer_start:
> hrtimer=000000007acc0071 function=tick_nohz_handler
> expires=21879000000 softexpires=21879000000 mode=ABS|PINNED|HARD
> was_armed=1
> <idle>-0       [002] d.h1.    21.900238: local_timer_entry: vector=236
> <idle>-0       [002] d.h1.    21.900238: hrtimer_expire_entry:
> hrtimer=000000007acc0071 function=tick_nohz_handler now=21879002056
> <idle>-0       [002] ..s1.    21.900246: timer_expire_entry:
> timer=0000000076975009 function=test_timer_fn [nohz_poll_timer_test]
> now=4294689147 baseclk=4294689147
> <idle>-0       [002] dN.2.    23.737243: hrtimer_start:
> hrtimer=000000007acc0071 function=tick_nohz_handler
> expires=23716000000 softexpires=23716000000 mode=ABS|PINNED|HARD
> was_armed=0
> <idle>-0       [002] dNh1.    23.737250: local_timer_entry: vector=236
> <idle>-0       [002] dNh1.    23.737251: hrtimer_expire_entry:
> hrtimer=000000007acc0071 function=tick_nohz_handler now=23716014595
> <idle>-0       [002] .Ns1.    23.737255: timer_expire_entry:
> timer=00000000134bb09d function=test_timer_fn [nohz_poll_timer_test]
> now=4294690984 baseclk=4294689177
> <idle>-0       [002] dN.1.    23.737261: csd_function_entry:
> func=watchdog_check_skew_remote, csd=00000000ecfea5e9
> 
> With the hunk applied:
> 
> <idle>-0       [002] dN.1.    10.363861: csd_function_entry:
> func=idle_cycle [nohz_poll_timer_test], csd=0000000046d09235
> <idle>-0       [002] dN.2.    10.414660: hrtimer_start:
> hrtimer=00000000ccc99756 function=tick_nohz_handler
> expires=10405000000 softexpires=10405000000 mode=ABS|PINNED|HARD
> was_armed=1
> <idle>-0       [002] d.h1.    10.425656: local_timer_entry: vector=236
> <idle>-0       [002] d.h1.    10.425656: hrtimer_expire_entry:
> hrtimer=00000000ccc99756 function=tick_nohz_handler now=10405001482
> <idle>-0       [002] .ns1.    10.425660: timer_expire_entry:
> timer=00000000654cb5a4 function=test_timer_fn [nohz_poll_timer_test]
> now=4294677672 baseclk=4294677672
> <idle>-0       [002] dN.2.    10.425661: hrtimer_start:
> hrtimer=00000000ccc99756 function=tick_nohz_handler
> expires=10435000000 softexpires=10435000000 mode=ABS|PINNED|HARD
> was_armed=0
> <idle>-0       [002] d.h1.    10.455656: local_timer_entry: vector=236
> <idle>-0       [002] d.h1.    10.455657: hrtimer_expire_entry:
> hrtimer=00000000ccc99756 function=tick_nohz_handler now=10435001994
> <idle>-0       [002] .ns1.    10.455659: timer_expire_entry:
> timer=00000000a060ca9a function=test_timer_fn [nohz_poll_timer_test]
> now=4294677702 baseclk=4294677702
> 
> With the hunk, the stopped tick firing for the first timer sets
> TIF_NEED_RESCHED, the polling loop exits and the tick is reprogrammed
> for the second timer within a few microseconds; the 10 iterations
> captured take 0.92s instead of ~18s. Without that hunk, the CPU stops
> spinning on an unrelated event.
> 
> So in my understanding tick_nohz_idle_exit() program the tick only for
> the earliest timer; when it expire, the tick is stopped and not
> rearmed in tick_nohz_handler() (HRTIMER_NORESTART). Without setting
> NEED_RESCHED if another timer has been queued it has to wait for
> another event that set NEED_RESCHED.

Hehe, you're right :)

Let's try another strategy then. TS_FLAG_INIDLE is what tells nohz_fool whether
to manage the tick through the idle loop or through the IRQ exit.

So why not calling tick_nohz_idle_enter() on each idle loop iterations? That is,
from cpuidle_idle_call(). And call tick_nohz_idle_exit() right before
cpu_idle_poll()?

Then you can remove tick_nohz_idle_restart_tick().

Just be careful: tick_nohz_idle_enter() and tick_nohz_idle_exit() may now be
unbalanced. If TS_FLAG_INIDLE is already set, tick_nohz_idle_enter() should
return early and tick_nohz_idle_exit() as well if !TS_FLAG_INIDLE.

Also IRQs may now be disabled while calling tick_nohz_idle_exit(), so it should
use local_irq_save() and not local_irq_disable(). OTOH tick_nohz_idle_enter()
should always expect IRQs disabled.

So the purpose is to move cpu_idle_poll() outside the dynticks idle logic, then
it's safe against nohz_full timer management, the tick keeps being stopped if
possible and it's only restarted for dynticks idle.

Thanks.

-- 
Frederic Weisbecker
SUSE Labs

  reply	other threads:[~2026-11-10 13:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-06 16:06 [PATCH 0/3] Stop the idle tick on polling idle on nohz_full CPUs Marco Crivellari
2026-11-06 16:06 ` [PATCH 1/3] tick/nohz: Re-evaluate the tick on polling idle and on user entry Marco Crivellari
2026-11-06 22:15   ` Frederic Weisbecker
2026-11-09 17:24     ` Marco Crivellari
2026-11-10 13:33       ` Frederic Weisbecker [this message]
2026-11-10 17:35         ` Marco Crivellari
2026-11-11  9:59           ` Frederic Weisbecker
2026-11-06 16:06 ` [PATCH 2/3] sched/idle: Stop the tick on polling idle on nohz_full CPUs Marco Crivellari
2026-11-06 21:55   ` Frederic Weisbecker
2026-11-10  8:27     ` Marco Crivellari
2026-11-06 16:06 ` [PATCH 3/3] Documentation: no_hz: Add tick stop in polling idle Marco Crivellari

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=avMdOa44c5qvryuH@localhost.localdomain \
    --to=frederic@kernel.org \
    --cc=anna-maria@linutronix.de \
    --cc=atomlin@atomlin.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marco.crivellari@suse.com \
    --cc=mhocko@suse.com \
    --cc=mingo@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=tglx@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.