@@ -1157,8 +1157,10 @@ void tick_nohz_idle_stop_tick(void)
11571157 ts -> idle_sleeps ++ ;
11581158 ts -> idle_expires = expires ;
11591159
1160- if (!was_stopped && tick_sched_flag_test (ts , TS_FLAG_STOPPED ))
1160+ if (!was_stopped && tick_sched_flag_test (ts , TS_FLAG_STOPPED )) {
1161+ kcpustat_dyntick_start (ts -> idle_entrytime );
11611162 nohz_balance_enter_idle (cpu );
1163+ }
11621164 } else {
11631165 tick_nohz_retain_tick (ts );
11641166 }
@@ -1200,7 +1202,6 @@ void tick_nohz_idle_enter(void)
12001202 WARN_ON_ONCE (ts -> timer_expires_base );
12011203 tick_sched_flag_set (ts , TS_FLAG_INIDLE );
12021204 ts -> idle_entrytime = ktime_get ();
1203- kcpustat_dyntick_start (ts -> idle_entrytime );
12041205 tick_nohz_clock_sleep (ts );
12051206
12061207 local_irq_enable ();
@@ -1230,9 +1231,10 @@ void tick_nohz_irq_exit(void)
12301231 struct tick_sched * ts = this_cpu_ptr (& tick_cpu_sched );
12311232
12321233 if (tick_sched_flag_test (ts , TS_FLAG_INIDLE )) {
1233- ts -> idle_entrytime = ktime_get ();
1234- kcpustat_irq_exit (ts -> idle_entrytime );
12351234 tick_nohz_clock_sleep (ts );
1235+ ts -> idle_entrytime = ktime_get ();
1236+ if (tick_sched_flag_test (ts , TS_FLAG_STOPPED ))
1237+ kcpustat_irq_exit (ts -> idle_entrytime );
12361238 } else {
12371239 tick_nohz_full_update_tick (ts );
12381240 }
@@ -1333,8 +1335,17 @@ void tick_nohz_idle_restart_tick(void)
13331335{
13341336 struct tick_sched * ts = this_cpu_ptr (& tick_cpu_sched );
13351337
1336- if (tick_sched_flag_test (ts , TS_FLAG_STOPPED ))
1337- tick_nohz_restart_sched_tick (ts , ktime_get ());
1338+ if (tick_sched_flag_test (ts , TS_FLAG_STOPPED )) {
1339+ /*
1340+ * Update entrytime here in case the tick restart is due to temporary
1341+ * polling on forced broadcast. The tick may be stopped again later within
1342+ * the same idle trip. The idle_entrytime was updated recently but make sure
1343+ * no tiny amount of idle time is accounted twice.
1344+ */
1345+ ts -> idle_entrytime = ktime_get ();
1346+ kcpustat_dyntick_stop (ts -> idle_entrytime );
1347+ tick_nohz_restart_sched_tick (ts , ts -> idle_entrytime );
1348+ }
13381349}
13391350
13401351static 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)
13641375void tick_nohz_idle_exit (void )
13651376{
13661377 struct tick_sched * ts = this_cpu_ptr (& tick_cpu_sched );
1367- bool idle_active , tick_stopped ;
13681378 ktime_t now ;
13691379
13701380 local_irq_disable ();
@@ -1373,18 +1383,13 @@ void tick_nohz_idle_exit(void)
13731383 WARN_ON_ONCE (ts -> timer_expires_base );
13741384
13751385 tick_sched_flag_clear (ts , TS_FLAG_INIDLE );
1376- idle_active = tick_sched_flag_test (ts , TS_FLAG_IDLE_ACTIVE );
1377- tick_stopped = tick_sched_flag_test (ts , TS_FLAG_STOPPED );
1386+ tick_nohz_clock_wakeup (ts );
13781387
1379- if (idle_active || tick_stopped )
1388+ if (tick_sched_flag_test ( ts , TS_FLAG_STOPPED )) {
13801389 now = ktime_get ();
1381-
1382- if (idle_active )
1383- tick_nohz_clock_wakeup (ts );
1384-
1385- if (tick_stopped )
1390+ kcpustat_dyntick_stop (now );
13861391 tick_nohz_idle_update_tick (ts , now );
1387- kcpustat_dyntick_stop ( now );
1392+ }
13881393
13891394 local_irq_enable ();
13901395}
@@ -1439,15 +1444,13 @@ static inline void tick_nohz_irq_enter(void)
14391444 struct tick_sched * ts = this_cpu_ptr (& tick_cpu_sched );
14401445 ktime_t now ;
14411446
1442- if (!tick_sched_flag_test (ts , TS_FLAG_STOPPED | TS_FLAG_IDLE_ACTIVE ))
1447+ tick_nohz_clock_wakeup (ts );
1448+
1449+ if (!tick_sched_flag_test (ts , TS_FLAG_STOPPED ))
14431450 return ;
14441451
14451452 now = ktime_get ();
1446-
1447- if (tick_sched_flag_test (ts , TS_FLAG_IDLE_ACTIVE )) {
1448- tick_nohz_clock_wakeup (ts );
1449- kcpustat_irq_enter (now );
1450- }
1453+ kcpustat_irq_enter (now );
14511454
14521455 /*
14531456 * 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)
14561459 * rare case (typically stop machine). So we must make sure we have a
14571460 * last resort.
14581461 */
1459- if (tick_sched_flag_test (ts , TS_FLAG_STOPPED ))
1460- tick_nohz_update_jiffies (now );
1462+ tick_nohz_update_jiffies (now );
14611463}
14621464
14631465#else
0 commit comments