diff options
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r-- | fs/btrfs/locking.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 47b0a88c12a2..a5310c0f41e2 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 | } |
@@ -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 | ||