Re: 2.6.15-rc7-rt1

From: Steven Rostedt
Date: Sun Jan 01 2006 - 10:34:06 EST



On Sun, 1 Jan 2006, Mark Knecht wrote:
>
> Hi all,
> Happy New Year.
>
> Is this the same problem Steven? It happened when running MythTV
> for the first time. Rerunning MythTV did not cause a second problem
> and the program then ran fine.
>
> - Mark
>
> ----------- [cut here ] --------- [please bite here ] ---------
> Kernel BUG at include/linux/timer.h:83

Looking at the above...

> invalid operand: 0000 [1] PREEMPT
> CPU 0

...

>
> Code: 0f 0b 68 9d 5f 42 80 c2 53 00 48 8b 35 25 54 2a 00 48 c7 c7
> RIP <ffffffff802ae2fa>{rtc_do_ioctl+730} RSP <ffff81000adb9e08>
>

And that rtc_do_ioctl, I would say "Yes".

Try out this patch and see if it fixes the problem. I'm reposting it just
so you don't need to go back and look for it.

-- Steve

Index: linux-2.6.15-rc7-rt1/drivers/char/rtc.c
===================================================================
--- linux-2.6.15-rc7-rt1.orig/drivers/char/rtc.c 2005-12-28 14:02:48.000000000 -0500
+++ linux-2.6.15-rc7-rt1/drivers/char/rtc.c 2005-12-31 14:41:58.000000000 -0500
@@ -384,7 +384,6 @@
}

#ifdef RTC_IRQ
-
/*
* A very tiny interrupt handler. It runs with SA_INTERRUPT set,
* but there is possibility of conflicting with the set_rtc_mmss()
@@ -397,8 +396,6 @@

irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- int mod;
-
/*
* Can be an alarm interrupt, update complete interrupt,
* or a periodic interrupt. We store the status in the
@@ -420,13 +417,10 @@
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
}

- mod = 0;
if (rtc_status & RTC_TIMER_ON)
- mod = 1;
+ mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);

spin_unlock (&rtc_lock);
- if (mod)
- mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);

/* Now do the rest of the actions */
spin_lock(&rtc_task_lock);
@@ -588,24 +582,18 @@
case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
{
unsigned long flags; /* can be called from isr via rtc_control() */
- int del = 0;
-
spin_lock_irqsave (&rtc_lock, flags);
mask_rtc_irq_bit_locked(RTC_PIE);
if (rtc_status & RTC_TIMER_ON) {
rtc_status &= ~RTC_TIMER_ON;
- del = 1;
+ del_timer(&rtc_irq_timer);
}
spin_unlock_irqrestore (&rtc_lock, flags);
- if (del)
- del_timer(&rtc_irq_timer);
return 0;
}
case RTC_PIE_ON: /* Allow periodic ints */
{
unsigned long flags; /* can be called from isr via rtc_control() */
- int add = 0;
-
/*
* We don't really want Joe User enabling more
* than 64Hz of interrupts on a multi-user machine.
@@ -617,13 +605,11 @@
spin_lock_irqsave (&rtc_lock, flags);
if (!(rtc_status & RTC_TIMER_ON)) {
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
+ add_timer(&rtc_irq_timer);
rtc_status |= RTC_TIMER_ON;
- add = 1;
}
set_rtc_irq_bit_locked(RTC_PIE);
spin_unlock_irqrestore (&rtc_lock, flags);
- if (add)
- add_timer(&rtc_irq_timer);
return 0;
}
case RTC_UIE_OFF: /* Mask ints from RTC updates. */
@@ -914,7 +900,6 @@
{
#ifdef RTC_IRQ
unsigned char tmp;
- int del;

if (rtc_has_irq == 0)
goto no_irq;
@@ -933,14 +918,11 @@
CMOS_WRITE(tmp, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
}
- del = 0;
if (rtc_status & RTC_TIMER_ON) {
rtc_status &= ~RTC_TIMER_ON;
- del = 1;
+ del_timer(&rtc_irq_timer);
}
spin_unlock_irq(&rtc_lock);
- if (del)
- del_timer(&rtc_irq_timer);

if (file->f_flags & FASYNC) {
rtc_fasync (-1, file, 0);
@@ -1017,7 +999,6 @@
return -EIO;
#else
unsigned char tmp;
- int del;

spin_lock_irq(&rtc_lock);
spin_lock(&rtc_task_lock);
@@ -1037,15 +1018,12 @@
CMOS_WRITE(tmp, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
}
- del = 0;
if (rtc_status & RTC_TIMER_ON) {
rtc_status &= ~RTC_TIMER_ON;
- del = 1;
+ del_timer(&rtc_irq_timer);
}
rtc_status &= ~RTC_IS_OPEN;
spin_unlock(&rtc_task_lock);
- if (del)
- del_timer(&rtc_irq_timer);
spin_unlock_irq(&rtc_lock);
return 0;
#endif
@@ -1307,7 +1285,6 @@
static void rtc_dropped_irq(unsigned long data)
{
unsigned long freq;
- int mod;

spin_lock_irq (&rtc_lock);

@@ -1317,9 +1294,8 @@
}

/* Just in case someone disabled the timer from behind our back... */
- mod = 0;
if (rtc_status & RTC_TIMER_ON)
- mod = 1;
+ mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);

rtc_irq_data += ((rtc_freq/HZ)<<8);
rtc_irq_data &= ~0xff;
@@ -1328,8 +1304,6 @@
freq = rtc_freq;

spin_unlock_irq(&rtc_lock);
- if (mod)
- mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);

printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/