diff options
Diffstat (limited to 'kernel/itimer.c')
-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..379be2f8c84c 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,18 +152,25 @@ 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); | ||
155 | if (ovalue) { | 158 | if (ovalue) { |
156 | ovalue->it_value = itimer_get_remtime(timer); | 159 | ovalue->it_value = itimer_get_remtime(timer); |
157 | ovalue->it_interval | 160 | ovalue->it_interval |
158 | = ktime_to_timeval(tsk->signal->it_real_incr); | 161 | = ktime_to_timeval(tsk->signal->it_real_incr); |
159 | } | 162 | } |
163 | /* We are sharing ->siglock with it_real_fn() */ | ||
164 | if (hrtimer_try_to_cancel(timer) < 0) { | ||
165 | spin_unlock_irq(&tsk->sighand->siglock); | ||
166 | goto again; | ||
167 | } | ||
160 | tsk->signal->it_real_incr = | 168 | tsk->signal->it_real_incr = |
161 | timeval_to_ktime(value->it_interval); | 169 | timeval_to_ktime(value->it_interval); |
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); |