diff options
-rw-r--r-- | fs/btrfs/disk-io.c | 16 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 1 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 2 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 18 |
4 files changed, 27 insertions, 10 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 92e14dd9bddb..bbba14b629d2 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -429,7 +429,7 @@ int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, | |||
429 | return 0; | 429 | return 0; |
430 | } | 430 | } |
431 | 431 | ||
432 | static unsigned long async_submit_limit(struct btrfs_fs_info *info) | 432 | unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info) |
433 | { | 433 | { |
434 | unsigned long limit = min_t(unsigned long, | 434 | unsigned long limit = min_t(unsigned long, |
435 | info->workers.max_workers, | 435 | info->workers.max_workers, |
@@ -439,7 +439,8 @@ static unsigned long async_submit_limit(struct btrfs_fs_info *info) | |||
439 | 439 | ||
440 | int btrfs_congested_async(struct btrfs_fs_info *info, int iodone) | 440 | int btrfs_congested_async(struct btrfs_fs_info *info, int iodone) |
441 | { | 441 | { |
442 | return atomic_read(&info->nr_async_bios) > async_submit_limit(info); | 442 | return atomic_read(&info->nr_async_bios) > |
443 | btrfs_async_submit_limit(info); | ||
443 | } | 444 | } |
444 | 445 | ||
445 | static void run_one_async_submit(struct btrfs_work *work) | 446 | static void run_one_async_submit(struct btrfs_work *work) |
@@ -451,12 +452,13 @@ static void run_one_async_submit(struct btrfs_work *work) | |||
451 | async = container_of(work, struct async_submit_bio, work); | 452 | async = container_of(work, struct async_submit_bio, work); |
452 | fs_info = BTRFS_I(async->inode)->root->fs_info; | 453 | fs_info = BTRFS_I(async->inode)->root->fs_info; |
453 | 454 | ||
454 | limit = async_submit_limit(fs_info); | 455 | limit = btrfs_async_submit_limit(fs_info); |
455 | limit = limit * 2 / 3; | 456 | limit = limit * 2 / 3; |
456 | 457 | ||
457 | atomic_dec(&fs_info->nr_async_submits); | 458 | atomic_dec(&fs_info->nr_async_submits); |
458 | 459 | ||
459 | if (atomic_read(&fs_info->nr_async_submits) < limit) | 460 | if (atomic_read(&fs_info->nr_async_submits) < limit && |
461 | waitqueue_active(&fs_info->async_submit_wait)) | ||
460 | wake_up(&fs_info->async_submit_wait); | 462 | wake_up(&fs_info->async_submit_wait); |
461 | 463 | ||
462 | async->submit_bio_hook(async->inode, async->rw, async->bio, | 464 | async->submit_bio_hook(async->inode, async->rw, async->bio, |
@@ -469,7 +471,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
469 | extent_submit_bio_hook_t *submit_bio_hook) | 471 | extent_submit_bio_hook_t *submit_bio_hook) |
470 | { | 472 | { |
471 | struct async_submit_bio *async; | 473 | struct async_submit_bio *async; |
472 | int limit = async_submit_limit(fs_info); | 474 | int limit = btrfs_async_submit_limit(fs_info); |
473 | 475 | ||
474 | async = kmalloc(sizeof(*async), GFP_NOFS); | 476 | async = kmalloc(sizeof(*async), GFP_NOFS); |
475 | if (!async) | 477 | if (!async) |
@@ -1863,10 +1865,10 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | |||
1863 | struct extent_io_tree *tree; | 1865 | struct extent_io_tree *tree; |
1864 | u64 num_dirty; | 1866 | u64 num_dirty; |
1865 | u64 start = 0; | 1867 | u64 start = 0; |
1866 | unsigned long thresh = 12 * 1024 * 1024; | 1868 | unsigned long thresh = 96 * 1024 * 1024; |
1867 | tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; | 1869 | tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; |
1868 | 1870 | ||
1869 | if (current_is_pdflush()) | 1871 | if (current_is_pdflush() || current->flags & PF_MEMALLOC) |
1870 | return; | 1872 | return; |
1871 | 1873 | ||
1872 | num_dirty = count_range_bits(tree, &start, (u64)-1, | 1874 | num_dirty = count_range_bits(tree, &start, (u64)-1, |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index e904a69347a4..2562a273ae18 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -73,4 +73,5 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
73 | int rw, struct bio *bio, int mirror_num, | 73 | int rw, struct bio *bio, int mirror_num, |
74 | extent_submit_bio_hook_t *submit_bio_hook); | 74 | extent_submit_bio_hook_t *submit_bio_hook); |
75 | int btrfs_congested_async(struct btrfs_fs_info *info, int iodone); | 75 | int btrfs_congested_async(struct btrfs_fs_info *info, int iodone); |
76 | unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info); | ||
76 | #endif | 77 | #endif |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 6bcb0876f9bb..eff3ad72991b 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -322,8 +322,6 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | |||
322 | if (ret) | 322 | if (ret) |
323 | break; | 323 | break; |
324 | while(start <= end) { | 324 | while(start <= end) { |
325 | if (btrfs_congested_async(root->fs_info, 0)) | ||
326 | congestion_wait(WRITE, HZ/10); | ||
327 | cond_resched(); | 325 | cond_resched(); |
328 | 326 | ||
329 | index = start >> PAGE_CACHE_SHIFT; | 327 | index = start >> PAGE_CACHE_SHIFT; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 23a5b0aba00a..2652660e6079 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -138,12 +138,18 @@ int run_scheduled_bios(struct btrfs_device *device) | |||
138 | { | 138 | { |
139 | struct bio *pending; | 139 | struct bio *pending; |
140 | struct backing_dev_info *bdi; | 140 | struct backing_dev_info *bdi; |
141 | struct btrfs_fs_info *fs_info; | ||
141 | struct bio *tail; | 142 | struct bio *tail; |
142 | struct bio *cur; | 143 | struct bio *cur; |
143 | int again = 0; | 144 | int again = 0; |
144 | unsigned long num_run = 0; | 145 | unsigned long num_run = 0; |
146 | unsigned long limit; | ||
145 | 147 | ||
146 | bdi = device->bdev->bd_inode->i_mapping->backing_dev_info; | 148 | bdi = device->bdev->bd_inode->i_mapping->backing_dev_info; |
149 | fs_info = device->dev_root->fs_info; | ||
150 | limit = btrfs_async_submit_limit(fs_info); | ||
151 | limit = limit * 2 / 3; | ||
152 | |||
147 | loop: | 153 | loop: |
148 | spin_lock(&device->io_lock); | 154 | spin_lock(&device->io_lock); |
149 | 155 | ||
@@ -179,7 +185,11 @@ loop: | |||
179 | cur = pending; | 185 | cur = pending; |
180 | pending = pending->bi_next; | 186 | pending = pending->bi_next; |
181 | cur->bi_next = NULL; | 187 | cur->bi_next = NULL; |
182 | atomic_dec(&device->dev_root->fs_info->nr_async_bios); | 188 | atomic_dec(&fs_info->nr_async_bios); |
189 | |||
190 | if (atomic_read(&fs_info->nr_async_bios) < limit && | ||
191 | waitqueue_active(&fs_info->async_submit_wait)) | ||
192 | wake_up(&fs_info->async_submit_wait); | ||
183 | 193 | ||
184 | BUG_ON(atomic_read(&cur->bi_cnt) == 0); | 194 | BUG_ON(atomic_read(&cur->bi_cnt) == 0); |
185 | bio_get(cur); | 195 | bio_get(cur); |
@@ -2135,6 +2145,7 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device, | |||
2135 | int rw, struct bio *bio) | 2145 | int rw, struct bio *bio) |
2136 | { | 2146 | { |
2137 | int should_queue = 1; | 2147 | int should_queue = 1; |
2148 | unsigned long limit; | ||
2138 | 2149 | ||
2139 | /* don't bother with additional async steps for reads, right now */ | 2150 | /* don't bother with additional async steps for reads, right now */ |
2140 | if (!(rw & (1 << BIO_RW))) { | 2151 | if (!(rw & (1 << BIO_RW))) { |
@@ -2171,6 +2182,11 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device, | |||
2171 | if (should_queue) | 2182 | if (should_queue) |
2172 | btrfs_queue_worker(&root->fs_info->submit_workers, | 2183 | btrfs_queue_worker(&root->fs_info->submit_workers, |
2173 | &device->work); | 2184 | &device->work); |
2185 | |||
2186 | limit = btrfs_async_submit_limit(root->fs_info); | ||
2187 | wait_event_timeout(root->fs_info->async_submit_wait, | ||
2188 | (atomic_read(&root->fs_info->nr_async_bios) < limit), | ||
2189 | HZ/10); | ||
2174 | return 0; | 2190 | return 0; |
2175 | } | 2191 | } |
2176 | 2192 | ||