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 640ded8f5c4..93d5e4a31fb 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -1450,8 +1450,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1450 | while (!signal_pending(current)) { | 1450 | while (!signal_pending(current)) { |
1451 | if (timer.it.cpu.expires.sched == 0) { | 1451 | if (timer.it.cpu.expires.sched == 0) { |
1452 | /* | 1452 | /* |
1453 | * Our timer fired and was reset. | 1453 | * Our timer fired and was reset, below |
1454 | * deletion can not fail. | ||
1454 | */ | 1455 | */ |
1456 | posix_cpu_timer_del(&timer); | ||
1455 | spin_unlock_irq(&timer.it_lock); | 1457 | spin_unlock_irq(&timer.it_lock); |
1456 | return 0; | 1458 | return 0; |
1457 | } | 1459 | } |
@@ -1469,9 +1471,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
1469 | * We were interrupted by a signal. | 1471 | * We were interrupted by a signal. |
1470 | */ | 1472 | */ |
1471 | sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); | 1473 | sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); |
1472 | posix_cpu_timer_set(&timer, 0, &zero_it, it); | 1474 | error = posix_cpu_timer_set(&timer, 0, &zero_it, it); |
1475 | if (!error) { | ||
1476 | /* | ||
1477 | * Timer is now unarmed, deletion can not fail. | ||
1478 | */ | ||
1479 | posix_cpu_timer_del(&timer); | ||
1480 | } | ||
1473 | spin_unlock_irq(&timer.it_lock); | 1481 | spin_unlock_irq(&timer.it_lock); |
1474 | 1482 | ||
1483 | while (error == TIMER_RETRY) { | ||
1484 | /* | ||
1485 | * We need to handle case when timer was or is in the | ||
1486 | * middle of firing. In other cases we already freed | ||
1487 | * resources. | ||
1488 | */ | ||
1489 | spin_lock_irq(&timer.it_lock); | ||
1490 | error = posix_cpu_timer_del(&timer); | ||
1491 | spin_unlock_irq(&timer.it_lock); | ||
1492 | } | ||
1493 | |||
1475 | if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { | 1494 | if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { |
1476 | /* | 1495 | /* |
1477 | * It actually did fire already. | 1496 | * It actually did fire already. |