Messages in this thread Patch in this message |  | | Date | Thu, 15 Jun 2006 20:11:15 +0400 | | From | Oleg Nesterov <> | | Subject | [PATCH 1/3] check_process_timers: fix possible lockup |
| |
If the local timer interrupt happens just after do_exit() sets PF_EXITING (and before it clears ->it_xxx_expires) run_posix_cpu_timers() will call check_process_timers() with tasklist_lock + ->siglock held and
check_process_timers:
t = tsk; do { ....
do { t = next_thread(t); } while (unlikely(t->flags & PF_EXITING)); } while (t != tsk);
the outer loop will never stop.
Actually, the window is bigger. Another process can attach the timer after ->it_xxx_expires was cleared (see the patch 2/3) and the 'if (PF_EXITING)' check in arm_timer() is racy (see the patch 3/3).
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
--- 2.6.17-rc6/kernel/posix-cpu-timers.c~1_CPT 2006-06-15 17:59:15.000000000 +0400 +++ 2.6.17-rc6/kernel/posix-cpu-timers.c 2006-06-15 18:01:57.000000000 +0400 @@ -1173,6 +1173,9 @@ static void check_process_timers(struct } t = tsk; do { + if (unlikely(t->flags & PF_EXITING)) + continue; + ticks = cputime_add(cputime_add(t->utime, t->stime), prof_left); if (!cputime_eq(prof_expires, cputime_zero) && @@ -1193,11 +1196,7 @@ static void check_process_timers(struct t->it_sched_expires > sched)) { t->it_sched_expires = sched; } - - do { - t = next_thread(t); - } while (unlikely(t->flags & PF_EXITING)); - } while (t != tsk); + } while ((t = next_thread(t)) != tsk); } } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |