|
@@ -1401,8 +1401,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
|
|
while (!signal_pending(current)) {
|
|
|
if (timer.it.cpu.expires.sched == 0) {
|
|
|
/*
|
|
|
- * Our timer fired and was reset.
|
|
|
+ * Our timer fired and was reset, below
|
|
|
+ * deletion can not fail.
|
|
|
*/
|
|
|
+ posix_cpu_timer_del(&timer);
|
|
|
spin_unlock_irq(&timer.it_lock);
|
|
|
return 0;
|
|
|
}
|
|
@@ -1420,9 +1422,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
|
|
* We were interrupted by a signal.
|
|
|
*/
|
|
|
sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
|
|
|
- posix_cpu_timer_set(&timer, 0, &zero_it, it);
|
|
|
+ error = posix_cpu_timer_set(&timer, 0, &zero_it, it);
|
|
|
+ if (!error) {
|
|
|
+ /*
|
|
|
+ * Timer is now unarmed, deletion can not fail.
|
|
|
+ */
|
|
|
+ posix_cpu_timer_del(&timer);
|
|
|
+ }
|
|
|
spin_unlock_irq(&timer.it_lock);
|
|
|
|
|
|
+ while (error == TIMER_RETRY) {
|
|
|
+ /*
|
|
|
+ * We need to handle case when timer was or is in the
|
|
|
+ * middle of firing. In other cases we already freed
|
|
|
+ * resources.
|
|
|
+ */
|
|
|
+ spin_lock_irq(&timer.it_lock);
|
|
|
+ error = posix_cpu_timer_del(&timer);
|
|
|
+ spin_unlock_irq(&timer.it_lock);
|
|
|
+ }
|
|
|
+
|
|
|
if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) {
|
|
|
/*
|
|
|
* It actually did fire already.
|