diff options
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r-- | fs/btrfs/locking.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 85506c4a3af7..1c36e5cd8f55 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
@@ -60,8 +60,8 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb) | |||
60 | 60 | ||
61 | /* | 61 | /* |
62 | * unfortunately, many of the places that currently set a lock to blocking | 62 | * unfortunately, many of the places that currently set a lock to blocking |
63 | * don't end up blocking for every long, and often they don't block | 63 | * don't end up blocking for very long, and often they don't block |
64 | * at all. For a dbench 50 run, if we don't spin one the blocking bit | 64 | * at all. For a dbench 50 run, if we don't spin on the blocking bit |
65 | * at all, the context switch rate can jump up to 400,000/sec or more. | 65 | * at all, the context switch rate can jump up to 400,000/sec or more. |
66 | * | 66 | * |
67 | * So, we're still stuck with this crummy spin on the blocking bit, | 67 | * So, we're still stuck with this crummy spin on the blocking bit, |
@@ -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 | } |
@@ -95,13 +96,15 @@ int btrfs_try_spin_lock(struct extent_buffer *eb) | |||
95 | { | 96 | { |
96 | int i; | 97 | int i; |
97 | 98 | ||
98 | spin_nested(eb); | 99 | if (btrfs_spin_on_block(eb)) { |
99 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | 100 | spin_nested(eb); |
100 | return 1; | 101 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) |
101 | spin_unlock(&eb->lock); | 102 | return 1; |
102 | 103 | spin_unlock(&eb->lock); | |
104 | } | ||
103 | /* spin for a bit on the BLOCKING flag */ | 105 | /* spin for a bit on the BLOCKING flag */ |
104 | for (i = 0; i < 2; i++) { | 106 | for (i = 0; i < 2; i++) { |
107 | cpu_relax(); | ||
105 | if (!btrfs_spin_on_block(eb)) | 108 | if (!btrfs_spin_on_block(eb)) |
106 | break; | 109 | break; |
107 | 110 | ||
@@ -148,6 +151,9 @@ int btrfs_tree_lock(struct extent_buffer *eb) | |||
148 | DEFINE_WAIT(wait); | 151 | DEFINE_WAIT(wait); |
149 | wait.func = btrfs_wake_function; | 152 | wait.func = btrfs_wake_function; |
150 | 153 | ||
154 | if (!btrfs_spin_on_block(eb)) | ||
155 | goto sleep; | ||
156 | |||
151 | while(1) { | 157 | while(1) { |
152 | spin_nested(eb); | 158 | spin_nested(eb); |
153 | 159 | ||
@@ -165,9 +171,10 @@ int btrfs_tree_lock(struct extent_buffer *eb) | |||
165 | * spin for a bit, and if the blocking flag goes away, | 171 | * spin for a bit, and if the blocking flag goes away, |
166 | * loop around | 172 | * loop around |
167 | */ | 173 | */ |
174 | cpu_relax(); | ||
168 | if (btrfs_spin_on_block(eb)) | 175 | if (btrfs_spin_on_block(eb)) |
169 | continue; | 176 | continue; |
170 | 177 | sleep: | |
171 | prepare_to_wait_exclusive(&eb->lock_wq, &wait, | 178 | prepare_to_wait_exclusive(&eb->lock_wq, &wait, |
172 | TASK_UNINTERRUPTIBLE); | 179 | TASK_UNINTERRUPTIBLE); |
173 | 180 | ||
@@ -220,8 +227,8 @@ int btrfs_tree_unlock(struct extent_buffer *eb) | |||
220 | return 0; | 227 | return 0; |
221 | } | 228 | } |
222 | 229 | ||
223 | int btrfs_tree_locked(struct extent_buffer *eb) | 230 | void btrfs_assert_tree_locked(struct extent_buffer *eb) |
224 | { | 231 | { |
225 | return test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags) || | 232 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) |
226 | spin_is_locked(&eb->lock); | 233 | assert_spin_locked(&eb->lock); |
227 | } | 234 | } |