From: Oleg Nesterov As Steven Rostedt pointed out, there are 2 problems with ITIMER_REAL timers. 1. do_setitimer() does not call del_timer_sync() in case when the timer is not pending (it_real_value() returns 0). This is wrong, the timer may still be running, and it can rearm itself. 2. It calls del_timer_sync() with tsk->sighand->siglock held. This is deadlockable, because timer's handler needs this lock too. Signed-off-by: Oleg Nesterov Acked-by: Steven Rostedt Cc: Ingo Molnar Signed-off-by: Andrew Morton --- kernel/itimer.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff -puN kernel/itimer.c~itimer_real-fix-possible-deadlock-and-race kernel/itimer.c --- 25/kernel/itimer.c~itimer_real-fix-possible-deadlock-and-race Fri Jun 24 14:41:19 2005 +++ 25-akpm/kernel/itimer.c Fri Jun 24 14:41:19 2005 @@ -153,11 +153,15 @@ int do_setitimer(int which, struct itime switch (which) { case ITIMER_REAL: +again: spin_lock_irq(&tsk->sighand->siglock); interval = tsk->signal->it_real_incr; val = it_real_value(tsk->signal); - if (val) - del_timer_sync(&tsk->signal->real_timer); + /* We are sharing ->siglock with it_real_fn() */ + if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) { + spin_unlock_irq(&tsk->sighand->siglock); + goto again; + } tsk->signal->it_real_incr = timeval_to_jiffies(&value->it_interval); it_real_arm(tsk, timeval_to_jiffies(&value->it_value)); _