aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rwsem-spinlock.c
diff options
context:
space:
mode:
authorMichel Lespinasse <walken@google.com>2013-05-07 09:45:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 10:20:16 -0400
commit8cf5322ce69afea1fab6a6270db24d057d664798 (patch)
treea7b49b135dc7703a4a709562178a847fb9bc4f77 /lib/rwsem-spinlock.c
parent9b0fc9c09f1b262b7fe697eba6b05095d78850e5 (diff)
rwsem: simplify __rwsem_do_wake
This is mostly for cleanup value: - We don't need several gotos to handle the case where the first waiter is a writer. Two simple tests will do (and generate very similar code). - In the remainder of the function, we know the first waiter is a reader, so we don't have to double check that. We can use do..while loops to iterate over the readers to wake (generates slightly better code). Signed-off-by: Michel Lespinasse <walken@google.com> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Acked-by: Davidlohr Bueso <davidlohr.bueso@hp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/rwsem-spinlock.c')
-rw-r--r--lib/rwsem-spinlock.c23
1 files changed, 7 insertions, 16 deletions
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c
index 5f117f37ac0a..9be8a9144978 100644
--- a/lib/rwsem-spinlock.c
+++ b/lib/rwsem-spinlock.c
@@ -70,26 +70,17 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite)
70 70
71 waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); 71 waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
72 72
73 if (!wakewrite) {
74 if (waiter->type == RWSEM_WAITING_FOR_WRITE)
75 goto out;
76 goto dont_wake_writers;
77 }
78
79 /*
80 * as we support write lock stealing, we can't set sem->activity
81 * to -1 here to indicate we get the lock. Instead, we wake it up
82 * to let it go get it again.
83 */
84 if (waiter->type == RWSEM_WAITING_FOR_WRITE) { 73 if (waiter->type == RWSEM_WAITING_FOR_WRITE) {
85 wake_up_process(waiter->task); 74 if (wakewrite)
75 /* Wake up a writer. Note that we do not grant it the
76 * lock - it will have to acquire it when it runs. */
77 wake_up_process(waiter->task);
86 goto out; 78 goto out;
87 } 79 }
88 80
89 /* grant an infinite number of read locks to the front of the queue */ 81 /* grant an infinite number of read locks to the front of the queue */
90 dont_wake_writers:
91 woken = 0; 82 woken = 0;
92 while (waiter->type == RWSEM_WAITING_FOR_READ) { 83 do {
93 struct list_head *next = waiter->list.next; 84 struct list_head *next = waiter->list.next;
94 85
95 list_del(&waiter->list); 86 list_del(&waiter->list);
@@ -99,10 +90,10 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite)
99 wake_up_process(tsk); 90 wake_up_process(tsk);
100 put_task_struct(tsk); 91 put_task_struct(tsk);
101 woken++; 92 woken++;
102 if (list_empty(&sem->wait_list)) 93 if (next == &sem->wait_list)
103 break; 94 break;
104 waiter = list_entry(next, struct rwsem_waiter, list); 95 waiter = list_entry(next, struct rwsem_waiter, list);
105 } 96 } while (waiter->type != RWSEM_WAITING_FOR_WRITE);
106 97
107 sem->activity += woken; 98 sem->activity += woken;
108 99