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 | |
| 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')
| -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 | ||
