aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2012-12-17 19:01:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-17 20:15:18 -0500
commit9390ef0c85fd065f01045fef708b046c98cda04c (patch)
tree22ae17e0d07a9386cd494a869f60df757cfc56d7 /include
parenta1fd3e24d8a484b3265a6d485202afe093c058f3 (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.h4
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
9struct percpu_rw_semaphore { 9struct 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;