diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2006-02-01 06:05:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-01 11:53:12 -0500 |
commit | bc1978d404befacd272d0321ef749cc3192e488b (patch) | |
tree | 4ec8c7de7df1052e5f9b87a77fc3a80bc67e587d | |
parent | 853609b61ef88b414ffd1613741aa59894334320 (diff) |
[PATCH] hrtimers: fixup itimer conversion
The itimer conversion removed the locking which protects the timer and
variables in the shared signal structure. Steven Rostedt found the problem in
the latest -rt patches.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | kernel/itimer.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/itimer.c b/kernel/itimer.c index c2c05c4ff28d..6433d0685506 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -49,9 +49,11 @@ int do_getitimer(int which, struct itimerval *value) | |||
49 | 49 | ||
50 | switch (which) { | 50 | switch (which) { |
51 | case ITIMER_REAL: | 51 | case ITIMER_REAL: |
52 | spin_lock_irq(&tsk->sighand->siglock); | ||
52 | value->it_value = itimer_get_remtime(&tsk->signal->real_timer); | 53 | value->it_value = itimer_get_remtime(&tsk->signal->real_timer); |
53 | value->it_interval = | 54 | value->it_interval = |
54 | ktime_to_timeval(tsk->signal->it_real_incr); | 55 | ktime_to_timeval(tsk->signal->it_real_incr); |
56 | spin_unlock_irq(&tsk->sighand->siglock); | ||
55 | break; | 57 | break; |
56 | case ITIMER_VIRTUAL: | 58 | case ITIMER_VIRTUAL: |
57 | read_lock(&tasklist_lock); | 59 | read_lock(&tasklist_lock); |
@@ -150,8 +152,14 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) | |||
150 | 152 | ||
151 | switch (which) { | 153 | switch (which) { |
152 | case ITIMER_REAL: | 154 | case ITIMER_REAL: |
155 | again: | ||
156 | spin_lock_irq(&tsk->sighand->siglock); | ||
153 | timer = &tsk->signal->real_timer; | 157 | timer = &tsk->signal->real_timer; |
154 | hrtimer_cancel(timer); | 158 | /* We are sharing ->siglock with it_real_fn() */ |
159 | if (hrtimer_try_to_cancel(timer) < 0) { | ||
160 | spin_unlock_irq(&tsk->sighand->siglock); | ||
161 | goto again; | ||
162 | } | ||
155 | if (ovalue) { | 163 | if (ovalue) { |
156 | ovalue->it_value = itimer_get_remtime(timer); | 164 | ovalue->it_value = itimer_get_remtime(timer); |
157 | ovalue->it_interval | 165 | ovalue->it_interval |
@@ -162,6 +170,7 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) | |||
162 | expires = timeval_to_ktime(value->it_value); | 170 | expires = timeval_to_ktime(value->it_value); |
163 | if (expires.tv64 != 0) | 171 | if (expires.tv64 != 0) |
164 | hrtimer_start(timer, expires, HRTIMER_REL); | 172 | hrtimer_start(timer, expires, HRTIMER_REL); |
173 | spin_unlock_irq(&tsk->sighand->siglock); | ||
165 | break; | 174 | break; |
166 | case ITIMER_VIRTUAL: | 175 | case ITIMER_VIRTUAL: |
167 | nval = timeval_to_cputime(&value->it_value); | 176 | nval = timeval_to_cputime(&value->it_value); |