Revert "Fix cpu timers exit deadlock and races"
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 21 Oct 2005 22:36:00 +0000 (15:36 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 21 Oct 2005 22:36:00 +0000 (15:36 -0700)
Revert commit e03d13e985d48ac4885382c9e3b1510c78bd047f, to be replaced
by a much nicer fix from Roland.

kernel/posix-cpu-timers.c

index b3f3edc475de16a56b85ef64c45dbcff6805d35b..7a51a5597c33e04ad5f3f86d121779189ca326b3 100644 (file)
@@ -387,19 +387,25 @@ int posix_cpu_timer_del(struct k_itimer *timer)
        if (unlikely(p == NULL))
                return 0;
 
-       spin_lock(&p->sighand->siglock);
        if (!list_empty(&timer->it.cpu.entry)) {
-               /*
-                * Take us off the task's timer list.  We don't need to
-                * take tasklist_lock and check for the task being reaped.
-                * If it was reaped, it already called posix_cpu_timers_exit
-                * and posix_cpu_timers_exit_group to clear all the timers
-                * that pointed to it.
-                */
-               list_del(&timer->it.cpu.entry);
-               put_task_struct(p);
+               read_lock(&tasklist_lock);
+               if (unlikely(p->signal == NULL)) {
+                       /*
+                        * We raced with the reaping of the task.
+                        * The deletion should have cleared us off the list.
+                        */
+                       BUG_ON(!list_empty(&timer->it.cpu.entry));
+               } else {
+                       /*
+                        * Take us off the task's timer list.
+                        */
+                       spin_lock(&p->sighand->siglock);
+                       list_del(&timer->it.cpu.entry);
+                       spin_unlock(&p->sighand->siglock);
+               }
+               read_unlock(&tasklist_lock);
        }
-       spin_unlock(&p->sighand->siglock);
+       put_task_struct(p);
 
        return 0;
 }