Re: RT and Cascade interrupts

From: Trond Myklebust
Date: Wed Jun 01 2005 - 17:53:48 EST


on den 01.06.2005 Klokka 16:59 (-0400) skreiv john cooper:
> Yes later versions of the patch do. The version at hand
> 40-04 is based on 2.6.11. We intend to sync-up with a
> more recent version of the RT patch pending resolution
> of this issue.

Well it is pointless to concentrate on an obviously buggy patch. Could
you please sync up to rc5-rt-V0.7.47-15 at least: that looks like it
might be working (or at least be close to working).

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.

Cheers,
Trond
timer.c | 14 +++++++++++++-
1 files changed, 13 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__);
+ return;
+ }
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__);
+ return;
+ }
}
/*
* Cascade timers:
@@ -498,6 +506,10 @@ repeat:
goto repeat;
}
}
+ if (unlikely(base->running_timer != timer)) {
+ printk("BUG in line %d: __run_timers() is non-reentrant!\n", __LINE__);
+ return;
+ }
set_running_timer(base, NULL);
spin_unlock_irq(&base->lock);
// if (waitqueue_active(&base->wait_running_timer))