mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "tip-bot2 for Frederic Weisbecker" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Frederic Weisbecker <frederic@kernel.org>,
	Thomas Gleixner <tglx@kernel.org>,
	Shrikanth Hegde <sshegde@linux.ibm.com>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: timers/nohz] tick/sched: Account tickless idle cputime only when tick is stopped
Date: Tue, 02 Jun 2026 19:30:08 -0000	[thread overview]
Message-ID: <178042860871.710.132262535683252498.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20260508131647.43868-12-frederic@kernel.org>

The following commit has been merged into the timers/nohz branch of tip:

Commit-ID:     6a1f6a9dd0736257f5e5af32dd955d186cdc075d
Gitweb:        https://git.kernel.org/tip/6a1f6a9dd0736257f5e5af32dd955d186cdc075d
Author:        Frederic Weisbecker <frederic@kernel.org>
AuthorDate:    Fri, 08 May 2026 15:16:43 +02:00
Committer:     Thomas Gleixner <tglx@kernel.org>
CommitterDate: Tue, 02 Jun 2026 21:27:26 +02:00

tick/sched: Account tickless idle cputime only when tick is stopped

There is no real point in switching to dyntick-idle cputime accounting mode
if the tick is not actually stopped. This just adds overhead, notably
fetching the GTOD, on each idle exit and each idle IRQ entry for no reason
during short idle trips.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Link: https://patch.msgid.link/20260508131647.43868-12-frederic@kernel.org
---
 kernel/time/tick-sched.c | 50 ++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index fa03cf7..c1ee0b2 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -1157,8 +1157,10 @@ void tick_nohz_idle_stop_tick(void)
 		ts->idle_sleeps++;
 		ts->idle_expires = expires;
 
-		if (!was_stopped && tick_sched_flag_test(ts, TS_FLAG_STOPPED))
+		if (!was_stopped && tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {
+			kcpustat_dyntick_start(ts->idle_entrytime);
 			nohz_balance_enter_idle(cpu);
+		}
 	} else {
 		tick_nohz_retain_tick(ts);
 	}
@@ -1200,7 +1202,6 @@ void tick_nohz_idle_enter(void)
 	WARN_ON_ONCE(ts->timer_expires_base);
 	tick_sched_flag_set(ts, TS_FLAG_INIDLE);
 	ts->idle_entrytime = ktime_get();
-	kcpustat_dyntick_start(ts->idle_entrytime);
 	tick_nohz_clock_sleep(ts);
 
 	local_irq_enable();
@@ -1230,9 +1231,10 @@ void tick_nohz_irq_exit(void)
 	struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
 
 	if (tick_sched_flag_test(ts, TS_FLAG_INIDLE)) {
-		ts->idle_entrytime = ktime_get();
-		kcpustat_irq_exit(ts->idle_entrytime);
 		tick_nohz_clock_sleep(ts);
+		ts->idle_entrytime = ktime_get();
+		if (tick_sched_flag_test(ts, TS_FLAG_STOPPED))
+			kcpustat_irq_exit(ts->idle_entrytime);
 	} else {
 		tick_nohz_full_update_tick(ts);
 	}
@@ -1333,8 +1335,17 @@ void tick_nohz_idle_restart_tick(void)
 {
 	struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
 
-	if (tick_sched_flag_test(ts, TS_FLAG_STOPPED))
-		tick_nohz_restart_sched_tick(ts, ktime_get());
+	if (tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {
+		/*
+		 * Update entrytime here in case the tick restart is due to temporary
+		 * polling on forced broadcast. The tick may be stopped again later within
+		 * the same idle trip. The idle_entrytime was updated recently but make sure
+		 * no tiny amount of idle time is accounted twice.
+		 */
+		ts->idle_entrytime = ktime_get();
+		kcpustat_dyntick_stop(ts->idle_entrytime);
+		tick_nohz_restart_sched_tick(ts, ts->idle_entrytime);
+	}
 }
 
 static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)
@@ -1364,7 +1375,6 @@ static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)
 void tick_nohz_idle_exit(void)
 {
 	struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
-	bool idle_active, tick_stopped;
 	ktime_t now;
 
 	local_irq_disable();
@@ -1373,18 +1383,13 @@ void tick_nohz_idle_exit(void)
 	WARN_ON_ONCE(ts->timer_expires_base);
 
 	tick_sched_flag_clear(ts, TS_FLAG_INIDLE);
-	idle_active = tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE);
-	tick_stopped = tick_sched_flag_test(ts, TS_FLAG_STOPPED);
+	tick_nohz_clock_wakeup(ts);
 
-	if (idle_active || tick_stopped)
+	if (tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {
 		now = ktime_get();
-
-	if (idle_active)
-		tick_nohz_clock_wakeup(ts);
-
-	if (tick_stopped)
+		kcpustat_dyntick_stop(now);
 		tick_nohz_idle_update_tick(ts, now);
-	kcpustat_dyntick_stop(now);
+	}
 
 	local_irq_enable();
 }
@@ -1439,15 +1444,13 @@ static inline void tick_nohz_irq_enter(void)
 	struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
 	ktime_t now;
 
-	if (!tick_sched_flag_test(ts, TS_FLAG_STOPPED | TS_FLAG_IDLE_ACTIVE))
+	tick_nohz_clock_wakeup(ts);
+
+	if (!tick_sched_flag_test(ts, TS_FLAG_STOPPED))
 		return;
 
 	now = ktime_get();
-
-	if (tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE)) {
-		tick_nohz_clock_wakeup(ts);
-		kcpustat_irq_enter(now);
-	}
+	kcpustat_irq_enter(now);
 
 	/*
 	 * If all CPUs are idle we may need to update a stale jiffies value.
@@ -1456,8 +1459,7 @@ static inline void tick_nohz_irq_enter(void)
 	 * rare case (typically stop machine). So we must make sure we have a
 	 * last resort.
 	 */
-	if (tick_sched_flag_test(ts, TS_FLAG_STOPPED))
-		tick_nohz_update_jiffies(now);
+	tick_nohz_update_jiffies(now);
 }
 
 #else

  reply	other threads:[~2026-06-02 19:30 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-08 13:16 [PATCH 00/15 v4] tick/sched: Refactor idle cputime accounting Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 01/15] tick/sched: Fix TOCTOU in nohz idle time fetch Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 02/15] sched/idle: Handle offlining first in idle loop Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 03/15] sched/cputime: Remove superfluous and error prone kcpustat_field() parameter Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 04/15] sched/cputime: Correctly support generic vtime idle time Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 05/15] powerpc/time: Prepare to stop elapsing in dynticks-idle Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 06/15] s390/time: " Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 07/15] tick/sched: Unify idle cputime accounting Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 08/15] tick/sched: Remove nohz disabled special case in cputime fetch Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 09/15] tick/sched: Move dyntick-idle cputime accounting to cputime code Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 10/15] tick/sched: Remove unused fields Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 11/15] tick/sched: Account tickless idle cputime only when tick is stopped Frederic Weisbecker
2026-06-02 19:30   ` tip-bot2 for Frederic Weisbecker [this message]
2026-05-08 13:16 ` [PATCH 12/15] tick/sched: Consolidate idle time fetching APIs Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 13/15] sched/cputime: Provide get_cpu_[idle|iowait]_time_us() off-case Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 14/15] sched/cputime: Handle idle irqtime gracefully Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-08 13:16 ` [PATCH 15/15] sched/cputime: Handle dyntick-idle steal time correctly Frederic Weisbecker
2026-06-02 19:30   ` [tip: timers/nohz] " tip-bot2 for Frederic Weisbecker
2026-05-26 10:42 ` [PATCH 00/15 v4] tick/sched: Refactor idle cputime accounting Frederic Weisbecker

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=178042860871.710.132262535683252498.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=frederic@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=sshegde@linux.ibm.com \
    --cc=tglx@kernel.org \
    --cc=x86@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®