mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: TeJun Huh <tejun@aratech.co.kr>
To: linux-kernel@vger.kernel.org
Cc: andrea@suse.de
Subject: [PATCH] irq_enter() / wait_on_irq(), synchronize_irq() race fix
Date: Tue, 26 Aug 2003 10:02:04 +0900	[thread overview]
Message-ID: <20030826010204.GB5139@atj.dyndns.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 872 bytes --]

 This patch fixes races between irq_enter() <-> wait_on_ira() and
irq_enter() <-> synchronize_irq().

 1. Archs which use bitops or spinlock for global_irq_lock
	- adds smp_mb() to [hard_]irq_enter()
	- adds smp_mb() to synchronize_irq()
	=> alpha, i386, ia64, mips, mips64, parisc, x86_64
	=> ppc also has atomic_inc() in hard_irq_enter(), so
	   smp_mb__after_atomic_inc() is used instead.

 2. Archs which use brlock for global_irq_lock
	- adds smp_mb() to synchronize_irq()
	=> ppc64, sparc, sparc64

 3. Archs with no SMP support
	- nothing needed
	=> arm, cris, generic, m68k, sh, sh64
 
 4. Archs which don't seem to need irq_enter() synchronization to
    disable irqs on on other CPUs.
	- I don't know.  Adds smp_mb() to synchronize_irq()?
	=> s390, s390x

 Please comment on how it should be done on s390 and s390x and point
out if anything is wrong.

-- 
tejun

[-- Attachment #2: patch.irqrace --]
[-- Type: text/plain, Size: 8189 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1098  -> 1.1100 
#	arch/mips64/kernel/irq.c	1.5     -> 1.6    
#	include/asm-ppc/hardirq.h	1.8     -> 1.9    
#	include/asm-x86_64/hardirq.h	1.1     -> 1.2    
#	arch/sparc/kernel/irq.c	1.12    -> 1.13   
#	arch/alpha/kernel/irq_smp.c	1.2     -> 1.3    
#	arch/i386/kernel/irq.c	1.7     -> 1.8    
#	arch/mips/kernel/irq.c	1.8     -> 1.9    
#	arch/x86_64/kernel/irq.c	1.2     -> 1.3    
#	include/asm-ia64/hardirq.h	1.4     -> 1.5    
#	include/asm-mips/hardirq.h	1.3     -> 1.4    
#	arch/ia64/kernel/irq.c	1.9     -> 1.10   
#	arch/sparc64/kernel/irq.c	1.13    -> 1.14   
#	include/asm-mips64/hardirq.h	1.2     -> 1.3    
#	include/asm-alpha/hardirq.h	1.3     -> 1.4    
#	include/asm-i386/hardirq.h	1.4     -> 1.5    
#	arch/ppc/kernel/irq.c	1.18    -> 1.19   
#	arch/parisc/kernel/irq_smp.c	1.1     -> 1.2    
#	arch/ppc64/kernel/irq.c	1.3     -> 1.4    
#	include/asm-parisc/hardirq.h	1.2     -> 1.3    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/08/26	tj@atj.dyndns.org	1.1099
# - irq_enter() / wait_on_irq(), synchronize_irq() race fix.
# --------------------------------------------
# 03/08/26	tj@atj.dyndns.org	1.1100
# - irq race fix applied to other architectures.
# --------------------------------------------
#
diff -Nru a/arch/alpha/kernel/irq_smp.c b/arch/alpha/kernel/irq_smp.c
--- a/arch/alpha/kernel/irq_smp.c	Tue Aug 26 10:01:05 2003
+++ b/arch/alpha/kernel/irq_smp.c	Tue Aug 26 10:01:05 2003
@@ -242,6 +242,7 @@
 	} while (global_count != local_count);
 #else
 	/* Jay's version.  */
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		cli();
 		sti();
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/i386/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -307,6 +307,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		/* Stupid approach */
 		cli();
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/ia64/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -344,6 +344,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		/* Stupid approach */
 		cli();
diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
--- a/arch/mips/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/mips/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -171,6 +171,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		/* Stupid approach */
 		cli();
diff -Nru a/arch/mips64/kernel/irq.c b/arch/mips64/kernel/irq.c
--- a/arch/mips64/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/mips64/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -171,6 +171,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		/* Stupid approach */
 		cli();
diff -Nru a/arch/parisc/kernel/irq_smp.c b/arch/parisc/kernel/irq_smp.c
--- a/arch/parisc/kernel/irq_smp.c	Tue Aug 26 10:01:05 2003
+++ b/arch/parisc/kernel/irq_smp.c	Tue Aug 26 10:01:05 2003
@@ -225,6 +225,7 @@
 synchronize_irq(void)
 {
 	/* Jay's version.  */
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		cli();
 		sti();
diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
--- a/arch/ppc/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/ppc/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -675,6 +675,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (atomic_read(&global_irq_count)) {
 		/* Stupid approach */
 		cli();
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/ppc64/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -666,6 +666,7 @@
 
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		cli();
 		sti();
diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
--- a/arch/sparc/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/sparc/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -243,6 +243,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		cli();
 		sti();
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/sparc64/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -592,6 +592,7 @@
 
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		cli();
 		sti();
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Tue Aug 26 10:01:05 2003
+++ b/arch/x86_64/kernel/irq.c	Tue Aug 26 10:01:05 2003
@@ -333,6 +333,7 @@
  */
 void synchronize_irq(void)
 {
+	smp_mb(); /* Sync with irq_enter() */
 	if (irqs_running()) {
 		/* Stupid approach */
 		cli();
diff -Nru a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
--- a/include/asm-alpha/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-alpha/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -75,6 +75,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (spin_is_locked(&global_irq_lock))
 		barrier();
 }
diff -Nru a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
--- a/include/asm-i386/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-i386/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -67,6 +67,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (test_bit(0,&global_irq_lock)) {
 		cpu_relax();
 	}
diff -Nru a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h
--- a/include/asm-ia64/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-ia64/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -80,6 +80,8 @@
 {
 	really_local_irq_count()++;
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (test_bit(0,&global_irq_lock)) {
 		/* nothing */;
 	}
diff -Nru a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h
--- a/include/asm-mips/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-mips/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -82,6 +82,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (spin_is_locked(&global_irq_lock))
 		barrier();
 }
diff -Nru a/include/asm-mips64/hardirq.h b/include/asm-mips64/hardirq.h
--- a/include/asm-mips64/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-mips64/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -81,6 +81,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (spin_is_locked(&global_irq_lock))
 		barrier();
 }
diff -Nru a/include/asm-parisc/hardirq.h b/include/asm-parisc/hardirq.h
--- a/include/asm-parisc/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-parisc/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -82,6 +82,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (spin_is_locked(&global_irq_lock))
 		barrier();
 }
diff -Nru a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h
--- a/include/asm-ppc/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-ppc/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -69,6 +69,7 @@
 
 	++local_irq_count(cpu);
 	atomic_inc(&global_irq_count);
+	smp_mb__after_atomic_inc(); /* Sync with wait_on_irq() and synchronize_irq() */
 	while (test_bit(0,&global_irq_lock)) {
 		if (cpu == global_irq_holder) {
 			printk("uh oh, interrupt while we hold global irq lock! (CPU %d)\n", cpu);
diff -Nru a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
--- a/include/asm-x86_64/hardirq.h	Tue Aug 26 10:01:05 2003
+++ b/include/asm-x86_64/hardirq.h	Tue Aug 26 10:01:05 2003
@@ -67,6 +67,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb(); /* Sync with wait_on_irq() and synchronize_irq() */
+
 	while (test_bit(0,&global_irq_lock)) {
 		cpu_relax();
 	}

             reply	other threads:[~2003-08-26  1:00 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-26  1:02 TeJun Huh [this message]
2003-08-26  1:11 ` TeJun Huh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030826010204.GB5139@atj.dyndns.org \
    --to=tejun@aratech.co.kr \
    --cc=andrea@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®