Date: Wed, 26 Aug 1998 21:10:26 +0200 (CEST)
From: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
To: Linux/m68k <linux-m68k@lists.linux-m68k.org>
Subject: L68K: race fixes
Sender: owner-linux-m68k@phil.uni-sb.de


While debugging IDE, I found these:

  - BUGFIX: hardirq_trylock() and hardirq_endlock()
  - Add __SMP__ case to hardirq.h (Hi Jes :-)
  - Reorder softirq.h so it resembles more to the ia32 version

All based on the contents of include/asm-i386/.

--- m68k-test/include/asm-m68k/hardirq.h.orig	Fri May 15 00:43:33 1998
+++ m68k-test/include/asm-m68k/hardirq.h	Wed Aug 26 14:43:16 1998
@@ -5,14 +5,61 @@
 
 extern unsigned int local_irq_count[NR_CPUS];
 
-#define in_interrupt() (local_irq_count[smp_processor_id()] + local_bh_count[smp_processor_id()] != 0)
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
 
-#define hardirq_trylock(cpu)	(++local_irq_count[cpu], (cpu) == 0)
-#define hardirq_endlock(cpu)	(--local_irq_count[cpu])
+#ifndef __SMP__
+
+#define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
+#define hardirq_endlock(cpu)	do { } while (0)
 
 #define hardirq_enter(cpu)	(local_irq_count[cpu]++)
 #define hardirq_exit(cpu)	(local_irq_count[cpu]--)
 
 #define synchronize_irq()	do { } while (0)
 
-#endif
+#else
+
+#include <asm/atomic.h>
+
+extern unsigned char global_irq_holder;
+extern unsigned volatile int global_irq_lock;
+extern atomic_t global_irq_count;
+
+static inline void release_irqlock(int cpu)
+{
+	/* if we didn't own the irq lock, just ignore.. */
+	if (global_irq_holder == (unsigned char) cpu) {
+		global_irq_holder = NO_PROC_ID;
+		clear_bit(0,&global_irq_lock);
+	}
+}
+
+static inline void hardirq_enter(int cpu)
+{
+	++local_irq_count[cpu];
+	atomic_inc(&global_irq_count);
+}
+
+static inline void hardirq_exit(int cpu)
+{
+	atomic_dec(&global_irq_count);
+	--local_irq_count[cpu];
+}
+
+static inline int hardirq_trylock(int cpu)
+{
+	return !atomic_read(&global_irq_count) && !test_bit(0,&global_irq_lock);
+}
+
+#define hardirq_endlock(cpu)	do { } while (0)
+
+extern void synchronize_irq(void);
+
+#endif /* __SMP__ */
+
+#endif /* __M68K_HARDIRQ_H */
--- m68k-test/include/asm-m68k/softirq.h.orig	Mon Aug 10 19:42:51 1998
+++ m68k-test/include/asm-m68k/softirq.h	Wed Aug 26 15:00:23 1998
@@ -6,6 +6,9 @@
  */
 
 #include <asm/atomic.h>
+#include <asm/hardirq.h>
+
+extern unsigned int local_bh_count[NR_CPUS];
 
 #define get_active_bhs()	(bh_mask & bh_active)
 #define clear_active_bhs(x)	atomic_clear_mask((x),&bh_active)
@@ -17,34 +20,17 @@
 	bh_mask |= 1 << nr;
 }
 
-extern inline void mark_bh(int nr)
-{
-	set_bit(nr, &bh_active);
-}
-
-/*
- * These use a mask count to correctly handle
- * nested disable/enable calls
- */
-extern inline void disable_bh(int nr)
+extern inline void remove_bh(int nr)
 {
+	bh_base[nr] = NULL;
 	bh_mask &= ~(1 << nr);
-	bh_mask_count[nr]++;
 }
 
-extern inline void enable_bh(int nr)
-{
-	if (!--bh_mask_count[nr])
-		bh_mask |= 1 << nr;
-}
-
-extern inline void remove_bh(int nr)
+extern inline void mark_bh(int nr)
 {
-	bh_base[nr] = NULL;
-	bh_mask &= ~(1 << nr);
+	set_bit(nr, &bh_active);
 }
 
-extern unsigned int local_bh_count[NR_CPUS];
 
 extern inline void start_bh_atomic(void)
 {
@@ -59,8 +45,26 @@
 }
 
 /* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)  (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
-#define softirq_endlock(cpu)  (local_bh_count[cpu] = 0)
+#define softirq_trylock(cpu)	(local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
+#define softirq_endlock(cpu)	(local_bh_count[cpu] = 0)
 #define synchronize_bh()	do { } while (0)
+
+
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
+extern inline void disable_bh(int nr)
+{
+	bh_mask &= ~(1 << nr);
+	bh_mask_count[nr]++;
+	synchronize_bh();
+}
+
+extern inline void enable_bh(int nr)
+{
+	if (!--bh_mask_count[nr])
+		bh_mask |= 1 << nr;
+}
 
 #endif

Greetings,

						Geert

--
Geert Uytterhoeven                     Geert.Uytterhoeven@cs.kuleuven.ac.be
Wavelets, Linux/{m68k~Amiga,PPC~CHRP}  http://www.cs.kuleuven.ac.be/~geert/
Department of Computer Science -- Katholieke Universiteit Leuven -- Belgium

