aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/fs.h
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2012-09-26 07:46:43 +0200
committerJens Axboe <axboe@kernel.dk>2012-09-26 07:46:43 +0200
commit62ac665ff9fc07497ca524bd20d6a96893d11071 (patch)
treedfd697e488fde4b46f1cb2ebfb380bb881115827 /include/linux/fs.h
parentFix a crash when block device is read and block size is changed at the same time (diff)
downloadlinux-dev-62ac665ff9fc07497ca524bd20d6a96893d11071.tar.xz
linux-dev-62ac665ff9fc07497ca524bd20d6a96893d11071.zip
blockdev: turn a rw semaphore into a percpu rw semaphore
This avoids cache line bouncing when many processes lock the semaphore for read. New percpu lock implementation The lock consists of an array of percpu unsigned integers, a boolean variable and a mutex. When we take the lock for read, we enter rcu read section, check for a "locked" variable. If it is false, we increase a percpu counter on the current cpu and exit the rcu section. If "locked" is true, we exit the rcu section, take the mutex and drop it (this waits until a writer finished) and retry. Unlocking for read just decreases percpu variable. Note that we can unlock on a difference cpu than where we locked, in this case the counter underflows. The sum of all percpu counters represents the number of processes that hold the lock for read. When we need to lock for write, we take the mutex, set "locked" variable to true and synchronize rcu. Since RCU has been synchronized, no processes can create new read locks. We wait until the sum of percpu counters is zero - when it is, there are no readers in the critical section. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r--include/linux/fs.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e60bbd0225d5..24e1229cdfe0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -10,6 +10,7 @@
#include <linux/ioctl.h>
#include <linux/blk_types.h>
#include <linux/types.h>
+#include <linux/percpu-rwsem.h>
/*
* It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -726,7 +727,7 @@ struct block_device {
/* Mutex for freeze */
struct mutex bd_fsfreeze_mutex;
/* A semaphore that prevents I/O while block size is being changed */
- struct rw_semaphore bd_block_size_semaphore;
+ struct percpu_rw_semaphore bd_block_size_semaphore;
};
/*