diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r-- | kernel/posix-cpu-timers.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index a278cad1d5d6..942ca27a28b7 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -1401,8 +1401,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1401 | while (!signal_pending(current)) { | 1401 | while (!signal_pending(current)) { |
1402 | if (timer.it.cpu.expires.sched == 0) { | 1402 | if (timer.it.cpu.expires.sched == 0) { |
1403 | /* | 1403 | /* |
1404 | * Our timer fired and was reset. | 1404 | * Our timer fired and was reset, below |
1405 | * deletion can not fail. | ||
1405 | */ | 1406 | */ |
1407 | posix_cpu_timer_del(&timer); | ||
1406 | spin_unlock_irq(&timer.it_lock); | 1408 | spin_unlock_irq(&timer.it_lock); |
1407 | return 0; | 1409 | return 0; |
1408 | } | 1410 | } |
@@ -1420,9 +1422,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1420 | * We were interrupted by a signal. | 1422 | * We were interrupted by a signal. |
1421 | */ | 1423 | */ |
1422 | sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); | 1424 | sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); |
1423 | posix_cpu_timer_set(&timer, 0, &zero_it, it); | 1425 | error = posix_cpu_timer_set(&timer, 0, &zero_it, it); |
1426 | if (!error) { | ||
1427 | /* | ||
1428 | * Timer is now unarmed, deletion can not fail. | ||
1429 | */ | ||
1430 | posix_cpu_timer_del(&timer); | ||
1431 | } | ||
1424 | spin_unlock_irq(&timer.it_lock); | 1432 | spin_unlock_irq(&timer.it_lock); |
1425 | 1433 | ||
1434 | while (error == TIMER_RETRY) { | ||
1435 | /* | ||
1436 | * We need to handle case when timer was or is in the | ||
1437 | * middle of firing. In other cases we already freed | ||
1438 | * resources. | ||
1439 | */ | ||
1440 | spin_lock_irq(&timer.it_lock); | ||
1441 | error = posix_cpu_timer_del(&timer); | ||
1442 | spin_unlock_irq(&timer.it_lock); | ||
1443 | } | ||
1444 | |||
1426 | if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { | 1445 | if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { |
1427 | /* | 1446 | /* |
1428 | * It actually did fire already. | 1447 | * It actually did fire already. |