diff options
author | Chris Mason <chris.mason@oracle.com> | 2009-03-12 20:12:45 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-03-24 16:14:27 -0400 |
commit | 66d7e85ea7c3628189d19b265495358f756cb463 (patch) | |
tree | ffd9484c6e80f90bcf0c4da2f41dda57c8d6eac5 /fs/btrfs/locking.c | |
parent | 7f366cfecfc126731f8ac505d72026d691dac79a (diff) |
Btrfs: Check for a blocking lock before taking the spin
This reduces contention on the extent buffer spin locks by testing for a
blocking lock before trying to take the spinlock.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r-- | fs/btrfs/locking.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 47b0a88c12a2..6d8db2f5c38d 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
@@ -71,12 +71,13 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb) | |||
71 | static int btrfs_spin_on_block(struct extent_buffer *eb) | 71 | static int btrfs_spin_on_block(struct extent_buffer *eb) |
72 | { | 72 | { |
73 | int i; | 73 | int i; |
74 | |||
74 | for (i = 0; i < 512; i++) { | 75 | for (i = 0; i < 512; i++) { |
75 | cpu_relax(); | ||
76 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | 76 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) |
77 | return 1; | 77 | return 1; |
78 | if (need_resched()) | 78 | if (need_resched()) |
79 | break; | 79 | break; |
80 | cpu_relax(); | ||
80 | } | 81 | } |
81 | return 0; | 82 | return 0; |
82 | } | 83 | } |
@@ -102,6 +103,7 @@ int btrfs_try_spin_lock(struct extent_buffer *eb) | |||
102 | 103 | ||
103 | /* spin for a bit on the BLOCKING flag */ | 104 | /* spin for a bit on the BLOCKING flag */ |
104 | for (i = 0; i < 2; i++) { | 105 | for (i = 0; i < 2; i++) { |
106 | cpu_relax(); | ||
105 | if (!btrfs_spin_on_block(eb)) | 107 | if (!btrfs_spin_on_block(eb)) |
106 | break; | 108 | break; |
107 | 109 | ||
@@ -148,6 +150,9 @@ int btrfs_tree_lock(struct extent_buffer *eb) | |||
148 | DEFINE_WAIT(wait); | 150 | DEFINE_WAIT(wait); |
149 | wait.func = btrfs_wake_function; | 151 | wait.func = btrfs_wake_function; |
150 | 152 | ||
153 | if (!btrfs_spin_on_block(eb)) | ||
154 | goto sleep; | ||
155 | |||
151 | while(1) { | 156 | while(1) { |
152 | spin_nested(eb); | 157 | spin_nested(eb); |
153 | 158 | ||
@@ -165,9 +170,10 @@ int btrfs_tree_lock(struct extent_buffer *eb) | |||
165 | * spin for a bit, and if the blocking flag goes away, | 170 | * spin for a bit, and if the blocking flag goes away, |
166 | * loop around | 171 | * loop around |
167 | */ | 172 | */ |
173 | cpu_relax(); | ||
168 | if (btrfs_spin_on_block(eb)) | 174 | if (btrfs_spin_on_block(eb)) |
169 | continue; | 175 | continue; |
170 | 176 | sleep: | |
171 | prepare_to_wait_exclusive(&eb->lock_wq, &wait, | 177 | prepare_to_wait_exclusive(&eb->lock_wq, &wait, |
172 | TASK_UNINTERRUPTIBLE); | 178 | TASK_UNINTERRUPTIBLE); |
173 | 179 | ||