diff options
author | Michel Lespinasse <walken@google.com> | 2010-08-09 20:21:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-09 23:45:11 -0400 |
commit | a8618a0e8a06f75c6efec2a5477861d704d48b28 (patch) | |
tree | 02679a316c5dea69e337ff65219d7c116f5a59aa | |
parent | 424acaaeb3a3932d64a9b4bd59df6cf72c22d8f3 (diff) |
rwsem: smaller wrappers around rwsem_down_failed_common
More code can be pushed from rwsem_down_read_failed and
rwsem_down_write_failed into rwsem_down_failed_common.
Following change adding down_read_critical infrastructure support also
enjoys having flags available in a register rather than having to fish it
out in the struct rwsem_waiter...
Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: David Howells <dhowells@redhat.com>
Cc: Mike Waychison <mikew@google.com>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Ying Han <yinghan@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | lib/rwsem.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/lib/rwsem.c b/lib/rwsem.c index 318d435dcebb..f236d7cd5cf3 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
@@ -171,8 +171,9 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wake_type) | |||
171 | */ | 171 | */ |
172 | static struct rw_semaphore __sched * | 172 | static struct rw_semaphore __sched * |
173 | rwsem_down_failed_common(struct rw_semaphore *sem, | 173 | rwsem_down_failed_common(struct rw_semaphore *sem, |
174 | struct rwsem_waiter *waiter, signed long adjustment) | 174 | unsigned int flags, signed long adjustment) |
175 | { | 175 | { |
176 | struct rwsem_waiter waiter; | ||
176 | struct task_struct *tsk = current; | 177 | struct task_struct *tsk = current; |
177 | signed long count; | 178 | signed long count; |
178 | 179 | ||
@@ -180,12 +181,13 @@ rwsem_down_failed_common(struct rw_semaphore *sem, | |||
180 | 181 | ||
181 | /* set up my own style of waitqueue */ | 182 | /* set up my own style of waitqueue */ |
182 | spin_lock_irq(&sem->wait_lock); | 183 | spin_lock_irq(&sem->wait_lock); |
183 | waiter->task = tsk; | 184 | waiter.task = tsk; |
185 | waiter.flags = flags; | ||
184 | get_task_struct(tsk); | 186 | get_task_struct(tsk); |
185 | 187 | ||
186 | if (list_empty(&sem->wait_list)) | 188 | if (list_empty(&sem->wait_list)) |
187 | adjustment += RWSEM_WAITING_BIAS; | 189 | adjustment += RWSEM_WAITING_BIAS; |
188 | list_add_tail(&waiter->list, &sem->wait_list); | 190 | list_add_tail(&waiter.list, &sem->wait_list); |
189 | 191 | ||
190 | /* we're now waiting on the lock, but no longer actively locking */ | 192 | /* we're now waiting on the lock, but no longer actively locking */ |
191 | count = rwsem_atomic_update(adjustment, sem); | 193 | count = rwsem_atomic_update(adjustment, sem); |
@@ -206,7 +208,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem, | |||
206 | 208 | ||
207 | /* wait to be given the lock */ | 209 | /* wait to be given the lock */ |
208 | for (;;) { | 210 | for (;;) { |
209 | if (!waiter->task) | 211 | if (!waiter.task) |
210 | break; | 212 | break; |
211 | schedule(); | 213 | schedule(); |
212 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 214 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
@@ -223,11 +225,8 @@ rwsem_down_failed_common(struct rw_semaphore *sem, | |||
223 | asmregparm struct rw_semaphore __sched * | 225 | asmregparm struct rw_semaphore __sched * |
224 | rwsem_down_read_failed(struct rw_semaphore *sem) | 226 | rwsem_down_read_failed(struct rw_semaphore *sem) |
225 | { | 227 | { |
226 | struct rwsem_waiter waiter; | 228 | return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_READ, |
227 | 229 | -RWSEM_ACTIVE_READ_BIAS); | |
228 | waiter.flags = RWSEM_WAITING_FOR_READ; | ||
229 | rwsem_down_failed_common(sem, &waiter, -RWSEM_ACTIVE_READ_BIAS); | ||
230 | return sem; | ||
231 | } | 230 | } |
232 | 231 | ||
233 | /* | 232 | /* |
@@ -236,12 +235,8 @@ rwsem_down_read_failed(struct rw_semaphore *sem) | |||
236 | asmregparm struct rw_semaphore __sched * | 235 | asmregparm struct rw_semaphore __sched * |
237 | rwsem_down_write_failed(struct rw_semaphore *sem) | 236 | rwsem_down_write_failed(struct rw_semaphore *sem) |
238 | { | 237 | { |
239 | struct rwsem_waiter waiter; | 238 | return rwsem_down_failed_common(sem, RWSEM_WAITING_FOR_WRITE, |
240 | 239 | -RWSEM_ACTIVE_WRITE_BIAS); | |
241 | waiter.flags = RWSEM_WAITING_FOR_WRITE; | ||
242 | rwsem_down_failed_common(sem, &waiter, -RWSEM_ACTIVE_WRITE_BIAS); | ||
243 | |||
244 | return sem; | ||
245 | } | 240 | } |
246 | 241 | ||
247 | /* | 242 | /* |