patch-2.1.83 linux/arch/i386/kernel/irq.c

Next file: linux/arch/i386/lib/checksum.c
Previous file: linux/arch/i386/kernel/i386_ksyms.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.82/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
@@ -421,7 +421,19 @@
 {
 	int count = MAXCOUNT;
 
-	while (atomic_read(&global_irq_count)) {
+	for (;;) {
+
+		/*
+		 * Wait until all interrupts are gone. Wait
+		 * for bottom half handlers unless we're
+		 * already executing in one..
+		 */
+		if (!atomic_read(&global_irq_count)) {
+			if (local_bh_count[cpu] || !atomic_read(&global_bh_count))
+				break;
+		}
+
+		/* Duh, we have to loop. Release the lock to avoid deadlocks */
 		clear_bit(0,&global_irq_lock);
 
 		for (;;) {
@@ -437,6 +449,8 @@
 				continue;
 			if (global_irq_lock)
 				continue;
+			if (!local_bh_count[cpu] && atomic_read(&global_bh_count))
+				continue;
 			if (!test_and_set_bit(0,&global_irq_lock))
 				break;
 		}
@@ -470,9 +484,11 @@
  */
 void synchronize_irq(void)
 {
-	/* Stupid approach */
-	cli();
-	sti();
+	if (atomic_read(&global_irq_count)) {
+		/* Stupid approach */
+		cli();
+		sti();
+	}
 }
 
 static inline void get_irqlock(int cpu)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov