aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-10-26 13:40:45 -0400
committerChris Mason <chris.mason@oracle.com>2010-10-29 11:25:36 -0400
commitbf9022e06af553553bc8f4e21ce36147ca6eae68 (patch)
treee33d9a25fc5ec8e03c1f0d5a4775c865e0520811
parente5bc2458293b2af6c0b94435965c68cc70974b56 (diff)
Btrfs: use the flusher threads for delalloc throttling
We have a fairly complex set of loops around walking our list of delalloc inodes when we find metadata delalloc space running low. It doesn't work very well, can use large amounts of CPU and doesn't do very efficient writeback. This switches us to kick the bdi flusher threads instead. All dirty data in btrfs is accounted as delalloc data, so this is very similar in terms of what it writes, but we're able to just kick off the IO and wait for progress. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent-tree.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 980d6a3c342c..59c8daaacf0c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3328,15 +3328,14 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3328 u64 reserved; 3328 u64 reserved;
3329 u64 max_reclaim; 3329 u64 max_reclaim;
3330 u64 reclaimed = 0; 3330 u64 reclaimed = 0;
3331 int no_reclaim = 0;
3332 int pause = 1; 3331 int pause = 1;
3333 int ret; 3332 int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
3334 3333
3335 block_rsv = &root->fs_info->delalloc_block_rsv; 3334 block_rsv = &root->fs_info->delalloc_block_rsv;
3336 space_info = block_rsv->space_info; 3335 space_info = block_rsv->space_info;
3337 spin_lock(&space_info->lock); 3336
3337 smp_mb();
3338 reserved = space_info->bytes_reserved; 3338 reserved = space_info->bytes_reserved;
3339 spin_unlock(&space_info->lock);
3340 3339
3341 if (reserved == 0) 3340 if (reserved == 0)
3342 return 0; 3341 return 0;
@@ -3344,20 +3343,11 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3344 max_reclaim = min(reserved, to_reclaim); 3343 max_reclaim = min(reserved, to_reclaim);
3345 3344
3346 while (1) { 3345 while (1) {
3347 ret = btrfs_start_one_delalloc_inode(root, trans ? 1 : 0, sync); 3346 /* have the flusher threads jump in and do some IO */
3348 if (!ret) { 3347 smp_mb();
3349 if (no_reclaim > 2) 3348 nr_pages = min_t(unsigned long, nr_pages,
3350 break; 3349 root->fs_info->delalloc_bytes >> PAGE_CACHE_SHIFT);
3351 no_reclaim++; 3350 writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
3352 __set_current_state(TASK_INTERRUPTIBLE);
3353 schedule_timeout(pause);
3354 pause <<= 1;
3355 if (pause > HZ / 10)
3356 pause = HZ / 10;
3357 } else {
3358 no_reclaim = 0;
3359 pause = 1;
3360 }
3361 3351
3362 spin_lock(&space_info->lock); 3352 spin_lock(&space_info->lock);
3363 if (reserved > space_info->bytes_reserved) 3353 if (reserved > space_info->bytes_reserved)
@@ -3370,6 +3360,13 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3370 3360
3371 if (trans && trans->transaction->blocked) 3361 if (trans && trans->transaction->blocked)
3372 return -EAGAIN; 3362 return -EAGAIN;
3363
3364 __set_current_state(TASK_INTERRUPTIBLE);
3365 schedule_timeout(pause);
3366 pause <<= 1;
3367 if (pause > HZ / 10)
3368 pause = HZ / 10;
3369
3373 } 3370 }
3374 return reclaimed >= to_reclaim; 3371 return reclaimed >= to_reclaim;
3375} 3372}