[patch] "big IRQ lock" removal, 2.5.27-A5

From: Ingo Molnar (mingo@elte.hu)
Date: Sun Jul 21 2002 - 15:41:36 EST


reviewed and fixed the apm.c hacks, it's now using the proper spinlocks
and not cli()/sti(). Latest full patch is at:

    http://redhat.com/~mingo/remove-irqlock-patches/remove-irqlock-2.5.27-A5

(the apm.c changes are attached as well.)

        Ingo

--- linux/arch/i386/kernel/apm.c.orig Sun Jul 21 20:37:10 2002
+++ linux/arch/i386/kernel/apm.c Sun Jul 21 22:36:42 2002
@@ -222,6 +222,8 @@
 
 #include <linux/sysrq.h>
 
+extern rwlock_t xtime_lock;
+extern spinlock_t i8253_lock;
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
 
@@ -1141,40 +1143,25 @@
 
 static void set_time(void)
 {
- unsigned long flags;
-
- if (got_clock_diff) { /* Must know time zone in order to set clock */
- save_flags(flags);
- cli();
+ if (got_clock_diff) /* Must know time zone in order to set clock */
                 CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
- restore_flags(flags);
- }
 }
 
 static void get_time_diff(void)
 {
 #ifndef CONFIG_APM_RTC_IS_GMT
- unsigned long flags;
-
         /*
          * Estimate time zone so that set_time can update the clock
          */
- save_flags(flags);
         clock_cmos_diff = -get_cmos_time();
- cli();
         clock_cmos_diff += CURRENT_TIME;
         got_clock_diff = 1;
- restore_flags(flags);
 #endif
 }
 
-static void reinit_timer(void)
+static inline void reinit_timer(void)
 {
 #ifdef INIT_TIMER_AFTER_SUSPEND
- unsigned long flags;
-
- save_flags(flags);
- cli();
         /* set the clock to 100 Hz */
         outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
         udelay(10);
@@ -1182,7 +1169,6 @@
         udelay(10);
         outb(LATCH >> 8 , 0x40); /* MSB */
         udelay(10);
- restore_flags(flags);
 #endif
 }
 
@@ -1203,13 +1189,21 @@
                 }
                 printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
         }
+ /* serialize with the timer interrupt */
+ write_lock_irq(&xtime_lock);
+
+ /* protect against access to timer chip registers */
+ spin_lock(&i8253_lock);
+
         get_time_diff();
- cli();
         err = set_system_power_state(APM_STATE_SUSPEND);
         reinit_timer();
         set_time();
         ignore_normal_resume = 1;
- sti();
+
+ spin_unlock(&i8253_lock);
+ write_unlock_irq(&xtime_lock);
+
         if (err == APM_NO_ERROR)
                 err = APM_SUCCESS;
         if (err != APM_SUCCESS)
@@ -1232,8 +1226,12 @@
 {
         int err;
 
+ /* serialize with the timer interrupt */
+ write_lock_irq(&xtime_lock);
         /* If needed, notify drivers here */
         get_time_diff();
+ write_unlock_irq(&xtime_lock);
+
         err = set_system_power_state(APM_STATE_STANDBY);
         if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
                 apm_error("standby", err);
@@ -1321,7 +1319,9 @@
                         ignore_bounce = 1;
                         if ((event != APM_NORMAL_RESUME)
                             || (ignore_normal_resume == 0)) {
+ write_lock_irq(&xtime_lock);
                                 set_time();
+ write_unlock_irq(&xtime_lock);
                                 pm_send_all(PM_RESUME, (void *)0);
                                 queue_event(event, NULL);
                         }
@@ -1336,7 +1336,9 @@
                         break;
 
                 case APM_UPDATE_TIME:
+ write_lock_irq(&xtime_lock);
                         set_time();
+ write_unlock_irq(&xtime_lock);
                         break;
 
                 case APM_CRITICAL_SUSPEND:

-
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/



This archive was generated by hypermail 2b29 : Tue Jul 23 2002 - 22:00:36 EST