diff options
| author | Nick Piggin <npiggin@kernel.dk> | 2010-08-17 14:37:33 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-18 08:35:46 -0400 |
| commit | 2a4419b5b2a77f3f4537c14f7ad7df95770655dd (patch) | |
| tree | ad66519a92b995920ecada788e4a08e265747545 /include/linux | |
| parent | 44672e4fbd40e2dda8bbce7d0f71d24dbfc7e00e (diff) | |
fs: fs_struct rwlock to spinlock
fs: fs_struct rwlock to spinlock
struct fs_struct.lock is an rwlock with the read-side used to protect root and
pwd members while taking references to them. Taking a reference to a path
typically requires just 2 atomic ops, so the critical section is very small.
Parallel read-side operations would have cacheline contention on the lock, the
dentry, and the vfsmount cachelines, so the rwlock is unlikely to ever give a
real parallelism increase.
Replace it with a spinlock to avoid one or two atomic operations in typical
path lookup fastpath.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/fs_struct.h | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index eca3d520213..a42b5bf02f8 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | struct fs_struct { | 6 | struct fs_struct { |
| 7 | int users; | 7 | int users; |
| 8 | rwlock_t lock; | 8 | spinlock_t lock; |
| 9 | int umask; | 9 | int umask; |
| 10 | int in_exec; | 10 | int in_exec; |
| 11 | struct path root, pwd; | 11 | struct path root, pwd; |
| @@ -23,29 +23,29 @@ extern int unshare_fs_struct(void); | |||
| 23 | 23 | ||
| 24 | static inline void get_fs_root(struct fs_struct *fs, struct path *root) | 24 | static inline void get_fs_root(struct fs_struct *fs, struct path *root) |
| 25 | { | 25 | { |
| 26 | read_lock(&fs->lock); | 26 | spin_lock(&fs->lock); |
| 27 | *root = fs->root; | 27 | *root = fs->root; |
| 28 | path_get(root); | 28 | path_get(root); |
| 29 | read_unlock(&fs->lock); | 29 | spin_unlock(&fs->lock); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) | 32 | static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) |
| 33 | { | 33 | { |
| 34 | read_lock(&fs->lock); | 34 | spin_lock(&fs->lock); |
| 35 | *pwd = fs->pwd; | 35 | *pwd = fs->pwd; |
| 36 | path_get(pwd); | 36 | path_get(pwd); |
| 37 | read_unlock(&fs->lock); | 37 | spin_unlock(&fs->lock); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, | 40 | static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, |
| 41 | struct path *pwd) | 41 | struct path *pwd) |
| 42 | { | 42 | { |
| 43 | read_lock(&fs->lock); | 43 | spin_lock(&fs->lock); |
| 44 | *root = fs->root; | 44 | *root = fs->root; |
| 45 | path_get(root); | 45 | path_get(root); |
| 46 | *pwd = fs->pwd; | 46 | *pwd = fs->pwd; |
| 47 | path_get(pwd); | 47 | path_get(pwd); |
| 48 | read_unlock(&fs->lock); | 48 | spin_unlock(&fs->lock); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | #endif /* _LINUX_FS_STRUCT_H */ | 51 | #endif /* _LINUX_FS_STRUCT_H */ |
