hrtimer: Allow concurrent hrtimer_start() for self restarting timers
authorPeter Zijlstra <peterz@infradead.org>
Tue, 20 May 2014 13:49:48 +0000 (15:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 18 Sep 2015 11:52:07 +0000 (13:52 +0200)
commit9747205d2dbe6bbf72325dc11fdebf83a5ac7a50
tree9211f5e7c956a5bd9f8ea004cf0fae76905450fd
parent353bd7db1b1f48c32ca1cfde03f80e666839cec2
hrtimer: Allow concurrent hrtimer_start() for self restarting timers

commit 5de2755c8c8b3a6b8414870e2c284914a2b42e4d upstream.

Because we drop cpu_base->lock around calling hrtimer::function, it is
possible for hrtimer_start() to come in between and enqueue the timer.

If hrtimer::function then returns HRTIMER_RESTART we'll hit the BUG_ON
because HRTIMER_STATE_ENQUEUED will be set.

Since the above is a perfectly valid scenario, remove the BUG_ON and
make the enqueue_hrtimer() call conditional on the timer not being
enqueued already.

NOTE: in that concurrent scenario its entirely common for both sites
to want to modify the hrtimer, since hrtimers don't provide
serialization themselves be sure to provide some such that the
hrtimer::function and the hrtimer_start() caller don't both try and
fudge the expiration state at the same time.

To that effect, add a WARN when someone tries to forward an already
enqueued timer, the most common way to change the expiry of self
restarting timers. Ideally we'd put the WARN in everything modifying
the expiry but most of that is inlines and we don't need the bloat.

Fixes: 2d44ae4d7135 ("hrtimer: clean up cpu->base locking tricks")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Roman Gushchin <klamm@yandex-team.ru>
Cc: Paul Turner <pjt@google.com>
Link: http://lkml.kernel.org/r/20150415113105.GT5029@twins.programming.kicks-ass.net
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[bwh: Backported to 3.2: adjust filename, context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
(cherry picked from commit ba4a679df78ffd52405af90aae3f4481c6945d6d)

Signed-off-by: Willy Tarreau <w@1wt.eu>
kernel/hrtimer.c