Re: start_kernel(): bug: interrupts were enabled early

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Kevin Hilman
Date: Wednesday, April 7, 2010 - 12:09 pm

Linus Torvalds <torvalds@linux-foundation.org> writes:


[...]


OK, I'll bite since I was seeing boot-time hangs on ARM (TI OMAP3) due
to this.  Patch below.

Kevin


From 7baff4008353bbfd2a2e2a4da22b87bc4efa4194 Mon Sep 17 00:00:00 2001
From: Kevin Hilman <khilman@deeprootsystems.com>
Date: Wed, 7 Apr 2010 11:52:46 -0700
Subject: [PATCH] rwsem generic spinlock: use IRQ save/restore spinlocks

rwsems can be used with IRQs disabled, particularily in early boot
before IRQs are enabled.  Currently the spin_unlock_irq() usage in the
slow-patch will unconditionally enable interrupts and cause problems
since interrupts are not yet initialized or enabled.

This patch uses save/restore versions of IRQ spinlocks in the slowpath
to ensure interrupts are not unintentionally disabled.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 lib/rwsem-spinlock.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c
index ccf95bf..ffc9fc7 100644
--- a/lib/rwsem-spinlock.c
+++ b/lib/rwsem-spinlock.c
@@ -143,13 +143,14 @@ void __sched __down_read(struct rw_semaphore *sem)
 {
 	struct rwsem_waiter waiter;
 	struct task_struct *tsk;
+	unsigned long flags;
 
-	spin_lock_irq(&sem->wait_lock);
+	spin_lock_irqsave(&sem->wait_lock, flags);
 
 	if (sem->activity >= 0 && list_empty(&sem->wait_list)) {
 		/* granted */
 		sem->activity++;
-		spin_unlock_irq(&sem->wait_lock);
+		spin_unlock_irqrestore(&sem->wait_lock, flags);
 		goto out;
 	}
 
@@ -164,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem)
 	list_add_tail(&waiter.list, &sem->wait_list);
 
 	/* we don't need to touch the semaphore struct anymore */
-	spin_unlock_irq(&sem->wait_lock);
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
 
 	/* wait to be given the lock */
 	for (;;) {
@@ -209,13 +210,14 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
 {
 	struct rwsem_waiter waiter;
 	struct task_struct *tsk;
+	unsigned long flags;
 
-	spin_lock_irq(&sem->wait_lock);
+	spin_lock_irqsave(&sem->wait_lock, flags);
 
 	if (sem->activity == 0 && list_empty(&sem->wait_list)) {
 		/* granted */
 		sem->activity = -1;
-		spin_unlock_irq(&sem->wait_lock);
+		spin_unlock_irqrestore(&sem->wait_lock, flags);
 		goto out;
 	}
 
@@ -230,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
 	list_add_tail(&waiter.list, &sem->wait_list);
 
 	/* we don't need to touch the semaphore struct anymore */
-	spin_unlock_irq(&sem->wait_lock);
+	spin_unlock_irqrestore(&sem->wait_lock, flags);
 
 	/* wait to be given the lock */
 	for (;;) {
-- 
1.7.0.2

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
start_kernel(): bug: interrupts were enabled early, Rabin Vincent, (Thu Mar 25, 12:41 pm)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Wed Mar 31, 1:40 pm)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Wed Mar 31, 1:52 pm)
Re: start_kernel(): bug: interrupts were enabled early, Matthew Wilcox, (Wed Mar 31, 2:01 pm)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Wed Mar 31, 2:05 pm)
Re: start_kernel(): bug: interrupts were enabled early, Russell King, (Wed Mar 31, 2:05 pm)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Wed Mar 31, 2:08 pm)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Wed Mar 31, 2:12 pm)
Re: start_kernel(): bug: interrupts were enabled early, Matthew Wilcox, (Wed Mar 31, 2:17 pm)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Wed Mar 31, 2:28 pm)
Re: start_kernel(): bug: interrupts were enabled early, Christoph Lameter, (Wed Mar 31, 2:42 pm)
Re: start_kernel(): bug: interrupts were enabled early, Russell King, (Wed Mar 31, 2:54 pm)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Wed Mar 31, 2:57 pm)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Wed Mar 31, 3:26 pm)
Re: start_kernel(): bug: interrupts were enabled early, Russell King, (Wed Mar 31, 3:30 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 3:31 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 3:35 pm)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Wed Mar 31, 3:36 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 3:36 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 3:37 pm)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Wed Mar 31, 3:49 pm)
Re: start_kernel(): bug: interrupts were enabled early, David Howells, (Wed Mar 31, 3:58 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 6:17 pm)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Wed Mar 31, 8:33 pm)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Wed Mar 31, 11:26 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 11:48 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Wed Mar 31, 11:50 pm)
Re: start_kernel(): bug: interrupts were enabled early, Jamie Lokier, (Thu Apr 1, 2:41 am)
Re: start_kernel(): bug: interrupts were enabled early, David Howells, (Thu Apr 1, 3:50 am)
Re: start_kernel(): bug: interrupts were enabled early, David Howells, (Thu Apr 1, 4:06 am)
Re: start_kernel(): bug: interrupts were enabled early, Matthew Wilcox, (Thu Apr 1, 4:23 am)
Re: start_kernel(): bug: interrupts were enabled early, Andrew Morton, (Thu Apr 1, 7:27 am)
Re: start_kernel(): bug: interrupts were enabled early, Christoph Lameter, (Thu Apr 1, 8:55 am)
Re: start_kernel(): bug: interrupts were enabled early, Christoph Lameter, (Thu Apr 1, 8:57 am)
Re: start_kernel(): bug: interrupts were enabled early, Linus Torvalds, (Thu Apr 1, 9:13 am)
Re: start_kernel(): bug: interrupts were enabled early, H. Peter Anvin, (Thu Apr 1, 9:15 am)
Re: start_kernel(): bug: interrupts were enabled early, Linus Torvalds, (Thu Apr 1, 1:12 pm)
Re: start_kernel(): bug: interrupts were enabled early, Benjamin Herrenschmidt, (Thu Apr 1, 4:00 pm)
Re: start_kernel(): bug: interrupts were enabled early, David Howells, (Fri Apr 2, 7:46 am)
Re: start_kernel(): bug: interrupts were enabled early, Linus Torvalds, (Fri Apr 2, 7:54 am)
Re: start_kernel(): bug: interrupts were enabled early, Kevin Hilman, (Wed Apr 7, 12:09 pm)
Re: start_kernel(): bug: interrupts were enabled early, =?utf-8?Q?Am=C3=A9ri ..., (Thu Apr 8, 8:55 am)