Re: Clear interrupts on a SMP machine?

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Wed Oct 18 2000 - 12:40:06 EST


On Wed, 18 Oct 2000, David Woodhouse wrote:

>
> root@chaos.analogic.com said:
> > There is no such exported variable in the 'stable' kernel tree:
>
> Then there should be, and the RTC accesses in 2.2 are probably racy.
>
> In which case, feel free to provide Alan with a patch for 2.2.18.
>
> --
> dwmw2
>
        2.2.17 should be able to do.

--- linux-2.2.17/arch/i386/kernel/i386_ksyms.c.orig Wed Oct 18 12:53:42 2000
+++ linux-2.2.17/arch/i386/kernel/i386_ksyms.c Wed Oct 18 12:55:55 2000
@@ -17,7 +17,7 @@
 #include <asm/hardirq.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
-
+extern spinlock_t rtc_lock;
 extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(elf_fpregset_t *);
 
@@ -41,7 +41,7 @@
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(disable_irq_nosync);
 EXPORT_SYMBOL(kernel_thread);
-
+EXPORT_SYMBOL(rtc_lock);
 EXPORT_SYMBOL(init_mm);
 
 EXPORT_SYMBOL_NOVERS(__down_failed);
--- linux-2.2.17/arch/i386/kernel/time.c.orig Wed Jun 7 17:26:42 2000
+++ linux-2.2.17/arch/i386/kernel/time.c Wed Oct 18 13:27:24 2000
@@ -28,6 +28,8 @@
  * 1998-12-24 Copyright (C) 1998 Andrea Arcangeli
  * Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
  * serialize accesses to xtime/lost_ticks).
+ * 2000-10-17 rjohnson@analogic.com
+ * Spin-lock added to RTC code and spin-lock exported.
  */
 
 #include <linux/errno.h>
@@ -294,13 +296,19 @@
  *
  * BUG: This routine does not handle hour overflow properly; it just
  * sets the minutes. Usually you'll only notice that after reboot!
+ *
  */
+
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+
 static int set_rtc_mmss(unsigned long nowtime)
 {
+ unsigned long flags;
         int retval = 0;
         int real_seconds, real_minutes, cmos_minutes;
         unsigned char save_control, save_freq_select;
 
+ spin_lock_irqsave(&rtc_lock, flags);
         save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
         CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
 
@@ -346,7 +354,7 @@
          */
         CMOS_WRITE(save_control, RTC_CONTROL);
         CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
+ spin_unlock_irqrestore(&rtc_lock, flags);
         return retval;
 }
 
@@ -496,9 +504,12 @@
 /* not static: needed by APM */
 unsigned long get_cmos_time(void)
 {
+ unsigned long flags;
         unsigned int year, mon, day, hour, min, sec;
         int i;
 
+ spin_lock_irqsave(&rtc_lock, flags);
+
         /* The Linux interpretation of the CMOS clock register contents:
          * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
          * RTC registers show the second which has precisely just started.
@@ -528,6 +539,7 @@
             BCD_TO_BIN(mon);
             BCD_TO_BIN(year);
           }
+ spin_unlock_irqrestore(&rtc_lock, flags);
         if ((year += 1900) < 1970)
                 year += 100;
         return mktime(year, mon, day, hour, min, sec);

Cheers,
Dick Johnson

Penguin : Linux version 2.2.17 on an i686 machine (801.18 BogoMips).

"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.

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



This archive was generated by hypermail 2b29 : Mon Oct 23 2000 - 21:00:13 EST