The following commit has been merged into the timers/core branch of tip:

Commit-ID:     dd2261ed45aaeddeb77768f291d604179bcab096
Gitweb:        
https://git.kernel.org/tip/dd2261ed45aaeddeb77768f291d604179bcab096
Author:        Julien Grall <[email protected]>
AuthorDate:    Wed, 21 Aug 2019 10:24:07 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Wed, 21 Aug 2019 16:10:01 +02:00

hrtimer: Protect lockless access to timer->base

The update to timer->base is protected by the base->cpu_base->lock().
However, hrtimer_cancel_wait_running() does access it lockless.  So the
compiler is allowed to refetch timer->base which can cause havoc when the
timer base is changed concurrently.

Use READ_ONCE() to prevent this.

[ tglx: Adapted from a RT patch ]

Signed-off-by: Julien Grall <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
---
 kernel/time/hrtimer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 8333537..f48864e 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1214,7 +1214,8 @@ static void hrtimer_sync_wait_running(struct 
hrtimer_cpu_base *cpu_base,
  */
 void hrtimer_cancel_wait_running(const struct hrtimer *timer)
 {
-       struct hrtimer_clock_base *base = timer->base;
+       /* Lockless read. Prevent the compiler from reloading it below */
+       struct hrtimer_clock_base *base = READ_ONCE(timer->base);
 
        if (!timer->is_soft || !base || !base->cpu_base) {
                cpu_relax();

Reply via email to