diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2009-11-17 23:14:12 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-11-18 16:32:12 +0100 |
commit | 8747d793fc5c4d3e4decd41d55f6dc24498dd5f5 (patch) | |
tree | 78983389e7e4656c755e81a97b5e08de0e640e04 /kernel | |
parent | timekeeping: Fix clock_gettime vsyscall time warp (diff) | |
download | linux-8747d793fc5c4d3e4decd41d55f6dc24498dd5f5.tar.xz linux-8747d793fc5c4d3e4decd41d55f6dc24498dd5f5.zip |
itimers: Fix racy writes to cpu_itimer fields
incr_error and error fields of struct cpu_itimer are used when calculating
next timer tick in check_cpu_itimers() and should not be modified without
tsk->sighand->siglock taken.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
LKML-Reference: <1253802903-979-1-git-send-email-sgruszka@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/itimer.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/kernel/itimer.c b/kernel/itimer.c index b03451ede528..d802883153da 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -146,6 +146,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, { cputime_t cval, nval, cinterval, ninterval; s64 ns_ninterval, ns_nval; + u32 error, incr_error; struct cpu_itimer *it = &tsk->signal->it[clock_id]; nval = timeval_to_cputime(&value->it_value); @@ -153,8 +154,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, ninterval = timeval_to_cputime(&value->it_interval); ns_ninterval = timeval_to_ns(&value->it_interval); - it->incr_error = cputime_sub_ns(ninterval, ns_ninterval); - it->error = cputime_sub_ns(nval, ns_nval); + error = cputime_sub_ns(nval, ns_nval); + incr_error = cputime_sub_ns(ninterval, ns_ninterval); spin_lock_irq(&tsk->sighand->siglock); @@ -168,6 +169,8 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, } it->expires = nval; it->incr = ninterval; + it->error = error; + it->incr_error = incr_error; trace_itimer_state(clock_id == CPUCLOCK_VIRT ? ITIMER_VIRTUAL : ITIMER_PROF, value, nval); |