diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 2423fcf29..5d3a5dabd 100755 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -497,7 +497,7 @@ void tick_resume(void) #ifdef CONFIG_SUSPEND static DEFINE_RAW_SPINLOCK(tick_freeze_lock); -static unsigned int tick_freeze_depth; +static unsigned long tick_frozen_mask; /** * tick_freeze - Suspend the local tick and (possibly) timekeeping. @@ -510,10 +510,17 @@ static unsigned int tick_freeze_depth; */ void tick_freeze(void) { + int cpu = smp_processor_id(); + raw_spin_lock(&tick_freeze_lock); - tick_freeze_depth++; - if (tick_freeze_depth == num_online_cpus()) { + tick_frozen_mask |= BIT(cpu); + if (tick_do_timer_cpu == cpu) { + cpu = ffz(tick_frozen_mask); + tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu : + TICK_DO_TIMER_NONE; + } + if (tick_frozen_mask == *cpumask_bits(cpu_online_mask)) { trace_suspend_resume(TPS("timekeeping_freeze"), smp_processor_id(), true); system_state = SYSTEM_SUSPEND; @@ -537,9 +544,11 @@ void tick_freeze(void) */ void tick_unfreeze(void) { + int cpu = smp_processor_id(); + raw_spin_lock(&tick_freeze_lock); - if (tick_freeze_depth == num_online_cpus()) { + if (tick_frozen_mask == *cpumask_bits(cpu_online_mask)) { timekeeping_resume(); sched_clock_resume(); system_state = SYSTEM_RUNNING; @@ -550,7 +559,7 @@ void tick_unfreeze(void) tick_resume_local(); } - tick_freeze_depth--; + tick_frozen_mask &= ~BIT(cpu); raw_spin_unlock(&tick_freeze_lock); }