lkml.org 
[lkml]   [2004]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [patch] Real-Time Preemption, -RT-2.6.9-mm1-V0

    * Ingo Molnar <mingo@elte.hu> wrote:

    > > does the quick hack below help?
    >
    > here's a more complete fix.

    third time lucky?

    Ingo

    --- linux/drivers/char/rtc.c.orig
    +++ linux/drivers/char/rtc.c
    @@ -177,7 +177,7 @@ static unsigned long rtc_max_user_freq =
    /*
    * rtc_task_lock nests inside rtc_lock.
    */
    -static DECLARE_SPINLOCK(rtc_task_lock);
    +static DECLARE_RAW_SPINLOCK(rtc_task_lock);
    static rtc_task_t *rtc_callback = NULL;
    #endif

    @@ -238,10 +238,17 @@ irqreturn_t rtc_interrupt(int irq, void
    rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
    }

    - if (rtc_status & RTC_TIMER_ON)
    + if (rtc_status & RTC_TIMER_ON) {
    + spin_unlock (&rtc_lock);
    + /*
    + * We do the mod_timer outside of the lock because
    + * it may reschedule under PREEMPT_REALTIME. As long
    + * as we read the flag race-free it is not a problem
    + * if two mod_timer()s race:
    + */
    mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
    -
    - spin_unlock (&rtc_lock);
    + } else
    + spin_unlock (&rtc_lock);

    /* Now do the rest of the actions */
    spin_lock(&rtc_task_lock);
    @@ -404,8 +411,8 @@ static int rtc_do_ioctl(unsigned int cmd
    if (rtc_status & RTC_TIMER_ON) {
    spin_lock_irq (&rtc_lock);
    rtc_status &= ~RTC_TIMER_ON;
    - del_timer(&rtc_irq_timer);
    spin_unlock_irq (&rtc_lock);
    + del_timer(&rtc_irq_timer); // FIXME
    }
    return 0;
    }
    @@ -730,9 +737,10 @@ static int rtc_release(struct inode *ino
    }
    if (rtc_status & RTC_TIMER_ON) {
    rtc_status &= ~RTC_TIMER_ON;
    - del_timer(&rtc_irq_timer);
    - }
    - spin_unlock_irq(&rtc_lock);
    + spin_unlock_irq(&rtc_lock);
    + del_timer(&rtc_irq_timer); // FIXME
    + } else
    + spin_unlock_irq(&rtc_lock);

    if (file->f_flags & FASYNC) {
    rtc_fasync (-1, file, 0);
    @@ -808,6 +816,7 @@ int rtc_unregister(rtc_task_t *task)
    return -EIO;
    #else
    unsigned char tmp;
    + int rm_timer;

    spin_lock_irq(&rtc_lock);
    spin_lock(&rtc_task_lock);
    @@ -827,13 +836,16 @@ int rtc_unregister(rtc_task_t *task)
    CMOS_WRITE(tmp, RTC_CONTROL);
    CMOS_READ(RTC_INTR_FLAGS);
    }
    + rm_timer = 0;
    if (rtc_status & RTC_TIMER_ON) {
    rtc_status &= ~RTC_TIMER_ON;
    - del_timer(&rtc_irq_timer);
    + rm_timer = 1;
    }
    rtc_status &= ~RTC_IS_OPEN;
    spin_unlock(&rtc_task_lock);
    spin_unlock_irq(&rtc_lock);
    + if (rm_timer)
    + del_timer(&rtc_irq_timer);
    return 0;
    #endif
    }
    @@ -1094,17 +1106,19 @@ static void rtc_dropped_irq(unsigned lon
    return;
    }

    - /* Just in case someone disabled the timer from behind our back... */
    - if (rtc_status & RTC_TIMER_ON)
    - mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
    -
    rtc_irq_data += ((rtc_freq/HZ)<<8);
    rtc_irq_data &= ~0xff;
    rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */

    freq = rtc_freq;

    - spin_unlock_irq(&rtc_lock);
    + /* Just in case someone disabled the timer from behind our back... */
    + if (rtc_status & RTC_TIMER_ON) {
    + spin_unlock_irq(&rtc_lock);
    + mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
    + } else
    + spin_unlock_irq(&rtc_lock);
    +

    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@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 14:07    [W:0.036 / U:30.400 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site