Messages in this thread Patch in this message | | | Subject | Re: RT and Cascade interrupts | From | Trond Myklebust <> | Date | Wed, 01 Jun 2005 19:09:16 -0400 |
| |
on den 01.06.2005 Klokka 18:51 (-0400) skreiv Trond Myklebust: > Could you then apply the following debugging patch? It should warn you > in case something happens to corrupt base->running_timer (something > which would screw up del_timer_sync()). I'm not sure that can happen, > but it might be worth checking.
Oops. You don't want to return without releasing the spinlock. This patch should be better...
Cheers, Trond timer.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletion(-)
Index: linux-2.6.12-rc5-rt-V0.7.47-15/kernel/timer.c =================================================================== --- linux-2.6.12-rc5-rt-V0.7.47-15.orig/kernel/timer.c +++ linux-2.6.12-rc5-rt-V0.7.47-15/kernel/timer.c @@ -436,7 +436,7 @@ static int cascade(tvec_base_t *base, tv static inline void __run_timers(tvec_base_t *base) { - struct timer_list *timer; + struct timer_list *timer = NULL; spin_lock_irq(&base->lock); while (time_after_eq(jiffies, base->timer_jiffies)) { @@ -444,6 +444,10 @@ static inline void __run_timers(tvec_bas struct list_head *head = &work_list; int index = base->timer_jiffies & TVR_MASK; + if (unlikely(base->running_timer != timer)) { + printk("BUG in line %d: __run_timers() is non-reentrant!\n", __LINE__); + goto out; + } if (softirq_need_resched()) { /* running_timer might be stale: */ set_running_timer(base, NULL); @@ -459,6 +463,10 @@ static inline void __run_timers(tvec_bas * valid. Any new jiffy will be taken care of in * subsequent loops: */ + if (unlikely(base->running_timer != timer)) { + printk("BUG in line %d: __run_timers() is non-reentrant!\n", __LINE__); + goto out; + } } /* * Cascade timers: @@ -498,7 +506,12 @@ repeat: goto repeat; } } + if (unlikely(base->running_timer != timer)) { + printk("BUG in line %d: __run_timers() is non-reentrant!\n", __LINE__); + goto out; + } set_running_timer(base, NULL); +out: spin_unlock_irq(&base->lock); // if (waitqueue_active(&base->wait_running_timer)) wake_up(&base->wait_for_running_timer); | |