diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r-- | kernel/posix-cpu-timers.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index a278cad1d5d6..8fd709c9bb58 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -155,11 +155,19 @@ static void bump_cpu_timer(struct k_itimer *timer, | |||
155 | 155 | ||
156 | static inline cputime_t prof_ticks(struct task_struct *p) | 156 | static inline cputime_t prof_ticks(struct task_struct *p) |
157 | { | 157 | { |
158 | return p->utime + p->stime; | 158 | cputime_t utime, stime; |
159 | |||
160 | task_cputime(p, &utime, &stime); | ||
161 | |||
162 | return utime + stime; | ||
159 | } | 163 | } |
160 | static inline cputime_t virt_ticks(struct task_struct *p) | 164 | static inline cputime_t virt_ticks(struct task_struct *p) |
161 | { | 165 | { |
162 | return p->utime; | 166 | cputime_t utime; |
167 | |||
168 | task_cputime(p, &utime, NULL); | ||
169 | |||
170 | return utime; | ||
163 | } | 171 | } |
164 | 172 | ||
165 | static int | 173 | static int |
@@ -471,18 +479,23 @@ static void cleanup_timers(struct list_head *head, | |||
471 | */ | 479 | */ |
472 | void posix_cpu_timers_exit(struct task_struct *tsk) | 480 | void posix_cpu_timers_exit(struct task_struct *tsk) |
473 | { | 481 | { |
482 | cputime_t utime, stime; | ||
483 | |||
474 | add_device_randomness((const void*) &tsk->se.sum_exec_runtime, | 484 | add_device_randomness((const void*) &tsk->se.sum_exec_runtime, |
475 | sizeof(unsigned long long)); | 485 | sizeof(unsigned long long)); |
486 | task_cputime(tsk, &utime, &stime); | ||
476 | cleanup_timers(tsk->cpu_timers, | 487 | cleanup_timers(tsk->cpu_timers, |
477 | tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); | 488 | utime, stime, tsk->se.sum_exec_runtime); |
478 | 489 | ||
479 | } | 490 | } |
480 | void posix_cpu_timers_exit_group(struct task_struct *tsk) | 491 | void posix_cpu_timers_exit_group(struct task_struct *tsk) |
481 | { | 492 | { |
482 | struct signal_struct *const sig = tsk->signal; | 493 | struct signal_struct *const sig = tsk->signal; |
494 | cputime_t utime, stime; | ||
483 | 495 | ||
496 | task_cputime(tsk, &utime, &stime); | ||
484 | cleanup_timers(tsk->signal->cpu_timers, | 497 | cleanup_timers(tsk->signal->cpu_timers, |
485 | tsk->utime + sig->utime, tsk->stime + sig->stime, | 498 | utime + sig->utime, stime + sig->stime, |
486 | tsk->se.sum_exec_runtime + sig->sum_sched_runtime); | 499 | tsk->se.sum_exec_runtime + sig->sum_sched_runtime); |
487 | } | 500 | } |
488 | 501 | ||
@@ -1226,11 +1239,14 @@ static inline int task_cputime_expired(const struct task_cputime *sample, | |||
1226 | static inline int fastpath_timer_check(struct task_struct *tsk) | 1239 | static inline int fastpath_timer_check(struct task_struct *tsk) |
1227 | { | 1240 | { |
1228 | struct signal_struct *sig; | 1241 | struct signal_struct *sig; |
1242 | cputime_t utime, stime; | ||
1243 | |||
1244 | task_cputime(tsk, &utime, &stime); | ||
1229 | 1245 | ||
1230 | if (!task_cputime_zero(&tsk->cputime_expires)) { | 1246 | if (!task_cputime_zero(&tsk->cputime_expires)) { |
1231 | struct task_cputime task_sample = { | 1247 | struct task_cputime task_sample = { |
1232 | .utime = tsk->utime, | 1248 | .utime = utime, |
1233 | .stime = tsk->stime, | 1249 | .stime = stime, |
1234 | .sum_exec_runtime = tsk->se.sum_exec_runtime | 1250 | .sum_exec_runtime = tsk->se.sum_exec_runtime |
1235 | }; | 1251 | }; |
1236 | 1252 | ||
@@ -1401,8 +1417,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1401 | while (!signal_pending(current)) { | 1417 | while (!signal_pending(current)) { |
1402 | if (timer.it.cpu.expires.sched == 0) { | 1418 | if (timer.it.cpu.expires.sched == 0) { |
1403 | /* | 1419 | /* |
1404 | * Our timer fired and was reset. | 1420 | * Our timer fired and was reset, below |
1421 | * deletion can not fail. | ||
1405 | */ | 1422 | */ |
1423 | posix_cpu_timer_del(&timer); | ||
1406 | spin_unlock_irq(&timer.it_lock); | 1424 | spin_unlock_irq(&timer.it_lock); |
1407 | return 0; | 1425 | return 0; |
1408 | } | 1426 | } |
@@ -1420,9 +1438,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1420 | * We were interrupted by a signal. | 1438 | * We were interrupted by a signal. |
1421 | */ | 1439 | */ |
1422 | sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); | 1440 | sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); |
1423 | posix_cpu_timer_set(&timer, 0, &zero_it, it); | 1441 | error = posix_cpu_timer_set(&timer, 0, &zero_it, it); |
1442 | if (!error) { | ||
1443 | /* | ||
1444 | * Timer is now unarmed, deletion can not fail. | ||
1445 | */ | ||
1446 | posix_cpu_timer_del(&timer); | ||
1447 | } | ||
1424 | spin_unlock_irq(&timer.it_lock); | 1448 | spin_unlock_irq(&timer.it_lock); |
1425 | 1449 | ||
1450 | while (error == TIMER_RETRY) { | ||
1451 | /* | ||
1452 | * We need to handle case when timer was or is in the | ||
1453 | * middle of firing. In other cases we already freed | ||
1454 | * resources. | ||
1455 | */ | ||
1456 | spin_lock_irq(&timer.it_lock); | ||
1457 | error = posix_cpu_timer_del(&timer); | ||
1458 | spin_unlock_irq(&timer.it_lock); | ||
1459 | } | ||
1460 | |||
1426 | if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { | 1461 | if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { |
1427 | /* | 1462 | /* |
1428 | * It actually did fire already. | 1463 | * It actually did fire already. |