Commit 3eac4abaa69949af0e2f64e5c55ee8a22bbdd3e7
Committed by
Linus Torvalds
1 parent
04287f975e
Exists in
master
and in
39 other branches
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> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 8 additions and 6 deletions Side-by-side Diff
lib/rwsem-spinlock.c
... | ... | @@ -143,13 +143,14 @@ |
143 | 143 | { |
144 | 144 | struct rwsem_waiter waiter; |
145 | 145 | struct task_struct *tsk; |
146 | + unsigned long flags; | |
146 | 147 | |
147 | - spin_lock_irq(&sem->wait_lock); | |
148 | + spin_lock_irqsave(&sem->wait_lock, flags); | |
148 | 149 | |
149 | 150 | if (sem->activity >= 0 && list_empty(&sem->wait_list)) { |
150 | 151 | /* granted */ |
151 | 152 | sem->activity++; |
152 | - spin_unlock_irq(&sem->wait_lock); | |
153 | + spin_unlock_irqrestore(&sem->wait_lock, flags); | |
153 | 154 | goto out; |
154 | 155 | } |
155 | 156 | |
... | ... | @@ -164,7 +165,7 @@ |
164 | 165 | list_add_tail(&waiter.list, &sem->wait_list); |
165 | 166 | |
166 | 167 | /* 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); | |
168 | 169 | |
169 | 170 | /* wait to be given the lock */ |
170 | 171 | for (;;) { |
171 | 172 | |
172 | 173 | |
... | ... | @@ -209,13 +210,14 @@ |
209 | 210 | { |
210 | 211 | struct rwsem_waiter waiter; |
211 | 212 | struct task_struct *tsk; |
213 | + unsigned long flags; | |
212 | 214 | |
213 | - spin_lock_irq(&sem->wait_lock); | |
215 | + spin_lock_irqsave(&sem->wait_lock, flags); | |
214 | 216 | |
215 | 217 | if (sem->activity == 0 && list_empty(&sem->wait_list)) { |
216 | 218 | /* granted */ |
217 | 219 | sem->activity = -1; |
218 | - spin_unlock_irq(&sem->wait_lock); | |
220 | + spin_unlock_irqrestore(&sem->wait_lock, flags); | |
219 | 221 | goto out; |
220 | 222 | } |
221 | 223 | |
... | ... | @@ -230,7 +232,7 @@ |
230 | 232 | list_add_tail(&waiter.list, &sem->wait_list); |
231 | 233 | |
232 | 234 | /* 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); | |
234 | 236 | |
235 | 237 | /* wait to be given the lock */ |
236 | 238 | for (;;) { |