Skip to content

Commit 3eac4ab

Browse files
metaliveblogtorvalds
authored andcommitted
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 <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 04287f9 commit 3eac4ab

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

lib/rwsem-spinlock.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,14 @@ void __sched __down_read(struct rw_semaphore *sem)
143143
{
144144
struct rwsem_waiter waiter;
145145
struct task_struct *tsk;
146+
unsigned long flags;
146147

147-
spin_lock_irq(&sem->wait_lock);
148+
spin_lock_irqsave(&sem->wait_lock, flags);
148149

149150
if (sem->activity >= 0 && list_empty(&sem->wait_list)) {
150151
/* granted */
151152
sem->activity++;
152-
spin_unlock_irq(&sem->wait_lock);
153+
spin_unlock_irqrestore(&sem->wait_lock, flags);
153154
goto out;
154155
}
155156

@@ -164,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem)
164165
list_add_tail(&waiter.list, &sem->wait_list);
165166

166167
/* we don't need to touch the semaphore struct anymore */
167-
spin_unlock_irq(&sem->wait_lock);
168+
spin_unlock_irqrestore(&sem->wait_lock, flags);
168169

169170
/* wait to be given the lock */
170171
for (;;) {
@@ -209,13 +210,14 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
209210
{
210211
struct rwsem_waiter waiter;
211212
struct task_struct *tsk;
213+
unsigned long flags;
212214

213-
spin_lock_irq(&sem->wait_lock);
215+
spin_lock_irqsave(&sem->wait_lock, flags);
214216

215217
if (sem->activity == 0 && list_empty(&sem->wait_list)) {
216218
/* granted */
217219
sem->activity = -1;
218-
spin_unlock_irq(&sem->wait_lock);
220+
spin_unlock_irqrestore(&sem->wait_lock, flags);
219221
goto out;
220222
}
221223

@@ -230,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
230232
list_add_tail(&waiter.list, &sem->wait_list);
231233

232234
/* we don't need to touch the semaphore struct anymore */
233-
spin_unlock_irq(&sem->wait_lock);
235+
spin_unlock_irqrestore(&sem->wait_lock, flags);
234236

235237
/* wait to be given the lock */
236238
for (;;) {

0 commit comments

Comments
 (0)