aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-08-04 08:20:15 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commit2dd3e67b1eaec8504da7e12b8afee77323a49f38 (patch)
tree794035de0243b20cda0fdf571e2ed02f29aa962e /fs/btrfs
parent65b51a009e29e64c0951f21ea17fdc66bbb0fbd7 (diff)
Btrfs: More throttle tuning
* Make walk_down_tree wake up throttled tasks more often * Make walk_down_tree call cond_resched during long loops * As the size of the ref cache grows, wait longer in throttle * Get rid of the reada code in walk_down_tree, the leaves don't get read anymore, thanks to the ref cache. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/disk-io.c13
-rw-r--r--fs/btrfs/extent-tree.c59
-rw-r--r--fs/btrfs/transaction.c15
3 files changed, 29 insertions, 58 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d2d1cc87e8ad..da9dda4338a3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -188,13 +188,6 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
188 btrfs_csum_final(crc, result); 188 btrfs_csum_final(crc, result);
189 189
190 if (verify) { 190 if (verify) {
191 int from_this_trans = 0;
192
193 if (root->fs_info->running_transaction &&
194 btrfs_header_generation(buf) ==
195 root->fs_info->running_transaction->transid)
196 from_this_trans = 1;
197
198 /* FIXME, this is not good */ 191 /* FIXME, this is not good */
199 if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) { 192 if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) {
200 u32 val; 193 u32 val;
@@ -203,11 +196,9 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
203 196
204 read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE); 197 read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE);
205 printk("btrfs: %s checksum verify failed on %llu " 198 printk("btrfs: %s checksum verify failed on %llu "
206 "wanted %X found %X from_this_trans %d " 199 "wanted %X found %X level %d\n",
207 "level %d\n",
208 root->fs_info->sb->s_id, 200 root->fs_info->sb->s_id,
209 buf->start, val, found, from_this_trans, 201 buf->start, val, found, btrfs_header_level(buf));
210 btrfs_header_level(buf));
211 return 1; 202 return 1;
212 } 203 }
213 } else { 204 } else {
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 98a1c0faedae..1aeb695078b9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2369,6 +2369,11 @@ static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans,
2369 leaf_owner, leaf_generation, 2369 leaf_owner, leaf_generation,
2370 key.objectid, key.offset, 0); 2370 key.objectid, key.offset, 0);
2371 mutex_unlock(&root->fs_info->alloc_mutex); 2371 mutex_unlock(&root->fs_info->alloc_mutex);
2372
2373 atomic_inc(&root->fs_info->throttle_gen);
2374 wake_up(&root->fs_info->transaction_throttle);
2375 cond_resched();
2376
2372 BUG_ON(ret); 2377 BUG_ON(ret);
2373 } 2378 }
2374 return 0; 2379 return 0;
@@ -2389,6 +2394,11 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans,
2389 ref->owner, ref->generation, 2394 ref->owner, ref->generation,
2390 info->objectid, info->offset, 0); 2395 info->objectid, info->offset, 0);
2391 mutex_unlock(&root->fs_info->alloc_mutex); 2396 mutex_unlock(&root->fs_info->alloc_mutex);
2397
2398 atomic_inc(&root->fs_info->throttle_gen);
2399 wake_up(&root->fs_info->transaction_throttle);
2400 cond_resched();
2401
2392 BUG_ON(ret); 2402 BUG_ON(ret);
2393 info++; 2403 info++;
2394 } 2404 }
@@ -2396,51 +2406,6 @@ static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans,
2396 return 0; 2406 return 0;
2397} 2407}
2398 2408
2399static void noinline reada_walk_down(struct btrfs_root *root,
2400 struct extent_buffer *node,
2401 int slot)
2402{
2403 u64 bytenr;
2404 u64 last = 0;
2405 u32 nritems;
2406 u32 refs;
2407 u32 blocksize;
2408 int ret;
2409 int i;
2410 int level;
2411 int skipped = 0;
2412
2413 nritems = btrfs_header_nritems(node);
2414 level = btrfs_header_level(node);
2415 if (level)
2416 return;
2417
2418 for (i = slot; i < nritems && skipped < 32; i++) {
2419 bytenr = btrfs_node_blockptr(node, i);
2420 if (last && ((bytenr > last && bytenr - last > 32 * 1024) ||
2421 (last > bytenr && last - bytenr > 32 * 1024))) {
2422 skipped++;
2423 continue;
2424 }
2425 blocksize = btrfs_level_size(root, level - 1);
2426 if (i != slot) {
2427 ret = lookup_extent_ref(NULL, root, bytenr,
2428 blocksize, &refs);
2429 BUG_ON(ret);
2430 if (refs != 1) {
2431 skipped++;
2432 continue;
2433 }
2434 }
2435 ret = readahead_tree_block(root, bytenr, blocksize,
2436 btrfs_node_ptr_generation(node, i));
2437 last = bytenr + blocksize;
2438 cond_resched();
2439 if (ret)
2440 break;
2441 }
2442}
2443
2444int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len, 2409int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len,
2445 u32 *refs) 2410 u32 *refs)
2446{ 2411{
@@ -2549,6 +2514,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2549 2514
2550 atomic_inc(&root->fs_info->throttle_gen); 2515 atomic_inc(&root->fs_info->throttle_gen);
2551 wake_up(&root->fs_info->transaction_throttle); 2516 wake_up(&root->fs_info->transaction_throttle);
2517 cond_resched();
2552 2518
2553 continue; 2519 continue;
2554 } 2520 }
@@ -2578,8 +2544,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2578 if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { 2544 if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
2579 free_extent_buffer(next); 2545 free_extent_buffer(next);
2580 2546
2581 if (path->slots[*level] == 0)
2582 reada_walk_down(root, cur, path->slots[*level]);
2583 next = read_tree_block(root, bytenr, blocksize, 2547 next = read_tree_block(root, bytenr, blocksize,
2584 ptr_gen); 2548 ptr_gen);
2585 cond_resched(); 2549 cond_resched();
@@ -2601,6 +2565,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2601 path->nodes[*level-1] = next; 2565 path->nodes[*level-1] = next;
2602 *level = btrfs_header_level(next); 2566 *level = btrfs_header_level(next);
2603 path->slots[*level] = 0; 2567 path->slots[*level] = 0;
2568 cond_resched();
2604 } 2569 }
2605out: 2570out:
2606 WARN_ON(*level < 0); 2571 WARN_ON(*level < 0);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 9d84daf10008..cf73342e8215 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -210,7 +210,9 @@ static noinline int wait_for_commit(struct btrfs_root *root,
210static void throttle_on_drops(struct btrfs_root *root) 210static void throttle_on_drops(struct btrfs_root *root)
211{ 211{
212 struct btrfs_fs_info *info = root->fs_info; 212 struct btrfs_fs_info *info = root->fs_info;
213 int harder_count = 0;
213 214
215harder:
214 if (atomic_read(&info->throttles)) { 216 if (atomic_read(&info->throttles)) {
215 DEFINE_WAIT(wait); 217 DEFINE_WAIT(wait);
216 int thr; 218 int thr;
@@ -226,6 +228,19 @@ static void throttle_on_drops(struct btrfs_root *root)
226 schedule(); 228 schedule();
227 finish_wait(&info->transaction_throttle, &wait); 229 finish_wait(&info->transaction_throttle, &wait);
228 } while (thr == atomic_read(&info->throttle_gen)); 230 } while (thr == atomic_read(&info->throttle_gen));
231 harder_count++;
232
233 if (root->fs_info->total_ref_cache_size > 1 * 1024 * 1024 &&
234 harder_count < 2)
235 goto harder;
236
237 if (root->fs_info->total_ref_cache_size > 5 * 1024 * 1024 &&
238 harder_count < 10)
239 goto harder;
240
241 if (root->fs_info->total_ref_cache_size > 10 * 1024 * 1024 &&
242 harder_count < 20)
243 goto harder;
229 } 244 }
230} 245}
231 246