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); |
