]> git.karo-electronics.de Git - karo-tx-linux.git/commit
timer: Kick dynticks targets on mod_timer*() calls
authorViresh Kumar <viresh.kumar@linaro.org>
Sat, 21 Jun 2014 23:29:14 +0000 (01:29 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 23 Jun 2014 09:23:47 +0000 (11:23 +0200)
commit9f6d9baaa8ca94b48aea495261cadaf2967c7784
treefec9f1a108808a1716ec72f3c40a4da72a396a08
parentd6f93829811a3e74f58e3c3823d507411eed651a
timer: Kick dynticks targets on mod_timer*() calls

When a timer is enqueued or modified on a dynticks target, that CPU
must re-evaluate the next tick to service that timer.

The tick re-evaluation is performed by an IPI kick on the target.
Now while we correctly call wake_up_nohz_cpu() from add_timer_on(), the
mod_timer*() API family doesn't support so well dynticks targets.

The reason for this is likely that __mod_timer() isn't supposed to
select an idle target for a timer, unless that target is the current
CPU, in which case a dynticks idle kick isn't actually needed.

But there is a small race window lurking behind that assumption: the
elected target has all the time to turn dynticks idle between the call
to get_nohz_timer_target() and the locking of its base. Hence a risk
that we enqueue a timer on a dynticks idle destination without kicking
it. As a result, the timer might be serviced too late in the future.

Also a target elected by __mod_timer() can be in full dynticks mode
and thus require to be kicked as well. And unlike idle dynticks, this
concern both local and remote targets.

To fix this whole issue, lets centralize the dynticks kick to
internal_add_timer() so that it is well handled for all sort of timer
enqueue. Even timer migration is concerned so that a full dynticks target
is correctly kicked as needed when timers are migrating to it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/1403393357-2070-3-git-send-email-fweisbec@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/time/timer.c