Skip to content

Commit b64a285

Browse files
committed
Btrfs: Wait for async bio submissions to make some progress at queue time
Before, the btrfs bdi congestion function was used to test for too many async bios. This keeps that check to throttle pdflush, but also adds a check while queuing bios. Signed-off-by: Chris Mason <[email protected]>
1 parent 4d1b5fb commit b64a285

File tree

4 files changed

+27
-10
lines changed

4 files changed

+27
-10
lines changed

fs/btrfs/disk-io.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
429429
return 0;
430430
}
431431

432-
static unsigned long async_submit_limit(struct btrfs_fs_info *info)
432+
unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info)
433433
{
434434
unsigned long limit = min_t(unsigned long,
435435
info->workers.max_workers,
@@ -439,7 +439,8 @@ static unsigned long async_submit_limit(struct btrfs_fs_info *info)
439439

440440
int btrfs_congested_async(struct btrfs_fs_info *info, int iodone)
441441
{
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);
443444
}
444445

445446
static void run_one_async_submit(struct btrfs_work *work)
@@ -451,12 +452,13 @@ static void run_one_async_submit(struct btrfs_work *work)
451452
async = container_of(work, struct async_submit_bio, work);
452453
fs_info = BTRFS_I(async->inode)->root->fs_info;
453454

454-
limit = async_submit_limit(fs_info);
455+
limit = btrfs_async_submit_limit(fs_info);
455456
limit = limit * 2 / 3;
456457

457458
atomic_dec(&fs_info->nr_async_submits);
458459

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))
460462
wake_up(&fs_info->async_submit_wait);
461463

462464
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,
469471
extent_submit_bio_hook_t *submit_bio_hook)
470472
{
471473
struct async_submit_bio *async;
472-
int limit = async_submit_limit(fs_info);
474+
int limit = btrfs_async_submit_limit(fs_info);
473475

474476
async = kmalloc(sizeof(*async), GFP_NOFS);
475477
if (!async)
@@ -1863,10 +1865,10 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
18631865
struct extent_io_tree *tree;
18641866
u64 num_dirty;
18651867
u64 start = 0;
1866-
unsigned long thresh = 12 * 1024 * 1024;
1868+
unsigned long thresh = 96 * 1024 * 1024;
18671869
tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
18681870

1869-
if (current_is_pdflush())
1871+
if (current_is_pdflush() || current->flags & PF_MEMALLOC)
18701872
return;
18711873

18721874
num_dirty = count_range_bits(tree, &start, (u64)-1,

fs/btrfs/disk-io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,5 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
7373
int rw, struct bio *bio, int mirror_num,
7474
extent_submit_bio_hook_t *submit_bio_hook);
7575
int btrfs_congested_async(struct btrfs_fs_info *info, int iodone);
76+
unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info);
7677
#endif

fs/btrfs/transaction.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,6 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
322322
if (ret)
323323
break;
324324
while(start <= end) {
325-
if (btrfs_congested_async(root->fs_info, 0))
326-
congestion_wait(WRITE, HZ/10);
327325
cond_resched();
328326

329327
index = start >> PAGE_CACHE_SHIFT;

fs/btrfs/volumes.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,18 @@ int run_scheduled_bios(struct btrfs_device *device)
138138
{
139139
struct bio *pending;
140140
struct backing_dev_info *bdi;
141+
struct btrfs_fs_info *fs_info;
141142
struct bio *tail;
142143
struct bio *cur;
143144
int again = 0;
144145
unsigned long num_run = 0;
146+
unsigned long limit;
145147

146148
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+
147153
loop:
148154
spin_lock(&device->io_lock);
149155

@@ -179,7 +185,11 @@ int run_scheduled_bios(struct btrfs_device *device)
179185
cur = pending;
180186
pending = pending->bi_next;
181187
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);
183193

184194
BUG_ON(atomic_read(&cur->bi_cnt) == 0);
185195
bio_get(cur);
@@ -2135,6 +2145,7 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device,
21352145
int rw, struct bio *bio)
21362146
{
21372147
int should_queue = 1;
2148+
unsigned long limit;
21382149

21392150
/* don't bother with additional async steps for reads, right now */
21402151
if (!(rw & (1 << BIO_RW))) {
@@ -2171,6 +2182,11 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device,
21712182
if (should_queue)
21722183
btrfs_queue_worker(&root->fs_info->submit_workers,
21732184
&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);
21742190
return 0;
21752191
}
21762192

0 commit comments

Comments
 (0)