Messages in this thread Patch in this message | | | Subject | Re: [BUG] Race condition with it_real_fn in kernel/itimer.c | From | Steven Rostedt <> | Date | Wed, 15 Jun 2005 17:01:29 -0400 |
| |
On Wed, 2005-06-15 at 13:25 -0700, Andrew Morton wrote:
> > And that will fix it. (Labels start in column zero, and a comment is > needed here).
I blame emacs for that bad label :-)
> > However I wonder if it would be sufficient to remove the del_timer_sync() > call altogether and just do mod_timer() in it_real_arm(). > > If the handler happens to be running on another CPU and if the handler > tries to run mod_timer() _after_ the do_setitimer() has run mod_timer(), > the handler will use the desired value of it_real_incr anyway. >
So do you prefer a patch like the following?
--- linux-2.6.12-rc6/kernel/itimer.c.orig 2005-06-15 16:33:13.000000000 -0400 +++ linux-2.6.12-rc6/kernel/itimer.c 2005-06-15 16:42:45.000000000 -0400 @@ -118,6 +118,8 @@ */ static inline void it_real_arm(struct task_struct *p, unsigned long interval) { + unsigned long expires; + p->signal->it_real_value = interval; /* XXX unnecessary field?? */ if (interval == 0) return; @@ -127,8 +129,8 @@ * the interval requested. This could happen if * time requested % (usecs per jiffy) is more than the usecs left * in the current jiffy */ - p->signal->real_timer.expires = jiffies + interval + 1; - add_timer(&p->signal->real_timer); + expires = jiffies + interval + 1; + mod_timer(&p->signal->real_timer, expires); } void it_real_fn(unsigned long __data) @@ -156,8 +158,6 @@ 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); tsk->signal->it_real_incr = timeval_to_jiffies(&value->it_interval); it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
Now the question is, what happens on the following scenario?
ksoftirqd:
calls it_real_func
process:
calls do_setitimer blocks on siglock;
ksoftirqd: unlocks siglock calls it_real_arm and after it assigns expires it takes an interrupt before calling mod_timer.
process:
calls it_real_arm and does the changes to mod_timer first.
ksoftirqd: comes back from interrupt and then calls mod_timer with the wrong value.
This may be a small chance in hell of happening, and the result may not be to drastic, but this is still a race condition. So far I think that my unconditional calling of del_timer_sync, although inefficient, it doesn't have any races.
-- Steve
- 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/
| |