Skip to content

Commit 500f8f9

Browse files
Frederic WeisbeckerKAGA-KOKO
authored andcommitted
tick: Assume timekeeping is correctly handed over upon last offline idle call
The timekeeping duty is handed over from the outgoing CPU on stop machine, then the oneshot tick is stopped right after. Therefore it's guaranteed that the current CPU isn't the timekeeper upon its last call to idle. Besides, calling tick_nohz_idle_stop_tick() while the dying CPU goes into idle suggests that the tick is going to be stopped while it is actually stopped already from the appropriate CPU hotplug state. Remove the confusing call and the obsolete case handling and convert it to a sanity check that verifies the above assumption. Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240225225508.11587-16-frederic@kernel.org
1 parent 3f69d04 commit 500f8f9

File tree

5 files changed

+8
-13
lines changed

5 files changed

+8
-13
lines changed

include/linux/tick.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ static inline void tick_cleanup_dead_cpu(int cpu) { }
2929

3030
#if defined(CONFIG_GENERIC_CLOCKEVENTS) && defined(CONFIG_HOTPLUG_CPU)
3131
extern int tick_cpu_dying(unsigned int cpu);
32+
extern void tick_assert_timekeeping_handover(void);
3233
#else
3334
#define tick_cpu_dying NULL
35+
static inline void tick_assert_timekeeping_handover(void) { }
3436
#endif
3537

3638
#if defined(CONFIG_GENERIC_CLOCKEVENTS) && defined(CONFIG_SUSPEND)

kernel/cpu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,7 @@ void cpuhp_report_idle_dead(void)
13991399
struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
14001400

14011401
BUG_ON(st->state != CPUHP_AP_OFFLINE);
1402+
tick_assert_timekeeping_handover();
14021403
rcutree_report_cpu_dead();
14031404
st->state = CPUHP_AP_IDLE_DEAD;
14041405
/*

kernel/sched/idle.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ static void do_idle(void)
291291
local_irq_disable();
292292

293293
if (cpu_is_offline(cpu)) {
294-
tick_nohz_idle_stop_tick();
295294
cpuhp_report_idle_dead();
296295
arch_cpu_idle_dead();
297296
}

kernel/time/tick-common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,10 @@ int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
396396
EXPORT_SYMBOL_GPL(tick_broadcast_oneshot_control);
397397

398398
#ifdef CONFIG_HOTPLUG_CPU
399+
void tick_assert_timekeeping_handover(void)
400+
{
401+
WARN_ON_ONCE(tick_do_timer_cpu == smp_processor_id());
402+
}
399403
/*
400404
* Stop the tick and transfer the timekeeping job away from a dying cpu.
401405
*/

kernel/time/tick-sched.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,18 +1160,7 @@ static bool report_idle_softirq(void)
11601160

11611161
static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
11621162
{
1163-
/*
1164-
* If this CPU is offline and it is the one which updates
1165-
* jiffies, then give up the assignment and let it be taken by
1166-
* the CPU which runs the tick timer next. If we don't drop
1167-
* this here, the jiffies might be stale and do_timer() never
1168-
* gets invoked.
1169-
*/
1170-
if (unlikely(!cpu_online(cpu))) {
1171-
if (cpu == tick_do_timer_cpu)
1172-
tick_do_timer_cpu = TICK_DO_TIMER_NONE;
1173-
return false;
1174-
}
1163+
WARN_ON_ONCE(cpu_is_offline(cpu));
11751164

11761165
if (unlikely(!tick_sched_flag_test(ts, TS_FLAG_NOHZ)))
11771166
return false;

0 commit comments

Comments
 (0)