diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-12-17 19:01:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-17 20:15:18 -0500 |
commit | 9390ef0c85fd065f01045fef708b046c98cda04c (patch) | |
tree | 22ae17e0d07a9386cd494a869f60df757cfc56d7 /include | |
parent | a1fd3e24d8a484b3265a6d485202afe093c058f3 (diff) |
percpu_rw_semaphore: kill ->writer_mutex, add ->write_ctr
percpu_rw_semaphore->writer_mutex was only added to simplify the initial
rewrite, the only thing it protects is clear_fast_ctr() which otherwise
could be called by multiple writers. ->rw_sem is enough to serialize the
writers.
Kill this mutex and add "atomic_t write_ctr" instead. The writers
increment/decrement this counter, the readers check it is zero instead of
mutex_is_locked().
Move atomic_add(clear_fast_ctr(), slow_read_ctr) under down_write() to
avoid the race with other writers. This is a bit sub-optimal, only the
first writer needs this and we do not need to exclude the readers at this
stage. But this is simple, we do not want another internal lock until we
add more features.
And this speeds up the write-contended case. Before this patch the racing
writers sleep in synchronize_sched_expedited() sequentially, with this
patch multiple synchronize_sched_expedited's can "overlap" with each
other. Note: we can do more optimizations, this is only the first step.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Anton Arapov <anton@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Mikulas Patocka <mpatocka@redhat.com>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/percpu-rwsem.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h index 592f0d610d8e..d2146a4f833e 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h | |||
@@ -1,14 +1,14 @@ | |||
1 | #ifndef _LINUX_PERCPU_RWSEM_H | 1 | #ifndef _LINUX_PERCPU_RWSEM_H |
2 | #define _LINUX_PERCPU_RWSEM_H | 2 | #define _LINUX_PERCPU_RWSEM_H |
3 | 3 | ||
4 | #include <linux/mutex.h> | 4 | #include <linux/atomic.h> |
5 | #include <linux/rwsem.h> | 5 | #include <linux/rwsem.h> |
6 | #include <linux/percpu.h> | 6 | #include <linux/percpu.h> |
7 | #include <linux/wait.h> | 7 | #include <linux/wait.h> |
8 | 8 | ||
9 | struct percpu_rw_semaphore { | 9 | struct percpu_rw_semaphore { |
10 | unsigned int __percpu *fast_read_ctr; | 10 | unsigned int __percpu *fast_read_ctr; |
11 | struct mutex writer_mutex; | 11 | atomic_t write_ctr; |
12 | struct rw_semaphore rw_sem; | 12 | struct rw_semaphore rw_sem; |
13 | atomic_t slow_read_ctr; | 13 | atomic_t slow_read_ctr; |
14 | wait_queue_head_t write_waitq; | 14 | wait_queue_head_t write_waitq; |