Skip to content

Commit

Permalink
nohz: Prepare to stop the tick on irq exit
Browse files Browse the repository at this point in the history
Interrupt exit is a natural place to stop the tick: it happens
after all events happening before and during the irq which
are liable to update the dependency on the tick occured. Also
it makes sure that any check on tick dependency is well ordered
against dynticks kick IPIs.

Bring in the infrastructure that performs the tick dependency
checks on irq exit and shut it down if these checks show that we
can do it safely.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Geoff Levand <geoff@infradead.org>
Cc: Gilad Ben Yossef <gilad@benyossef.com>
Cc: Hakan Akkan <hakanakkan@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kevin Hilman <khilman@linaro.org>
Cc: Li Zhong <zhong@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Frederic Weisbecker committed Apr 22, 2013
1 parent 9014c45 commit 5811d99
Showing 1 changed file with 25 additions and 6 deletions.
31 changes: 25 additions & 6 deletions kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,24 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
return ret;
}

static void tick_nohz_full_stop_tick(struct tick_sched *ts)
{
#ifdef CONFIG_NO_HZ_FULL
int cpu = smp_processor_id();

if (!tick_nohz_full_cpu(cpu) || is_idle_task(current))
return;

if (!ts->tick_stopped && ts->nohz_mode == NOHZ_MODE_INACTIVE)
return;

if (!can_stop_full_tick())
return;

tick_nohz_stop_sched_tick(ts, ktime_get(), cpu);
#endif
}

static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
{
/*
Expand Down Expand Up @@ -773,12 +791,13 @@ void tick_nohz_irq_exit(void)
{
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);

if (!ts->inidle)
return;

/* Cancel the timer because CPU already waken up from the C-states*/
menu_hrtimer_cancel();
__tick_nohz_idle_enter(ts);
if (ts->inidle) {
/* Cancel the timer because CPU already waken up from the C-states*/
menu_hrtimer_cancel();
__tick_nohz_idle_enter(ts);
} else {
tick_nohz_full_stop_tick(ts);
}
}

/**
Expand Down

0 comments on commit 5811d99

Please sign in to comment.