Skip to content

Commit

Permalink
Btrfs: add support for blkio controllers
Browse files Browse the repository at this point in the history
This attaches accounting information to bios as we submit them so the
new blkio controllers can throttle on btrfs filesystems.

Not much is required, we're just associating bios with blkcgs during clone,
calling wbc_init_bio()/wbc_account_io() during writepages submission,
and attaching the bios to the current context during direct IO.

Finally if we are splitting bios during btrfs_map_bio, this attaches
accounting information to the split.

The end result is able to throttle nicely on single disk filesystems.  A
little more work is required for multi-device filesystems.

Signed-off-by: Chris Mason <clm@fb.com>
  • Loading branch information
Chris Mason committed Aug 9, 2015
1 parent a4027a2 commit da2f0f7
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 4 deletions.
1 change: 1 addition & 0 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,7 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE;
bdi->congested_fn = btrfs_congested_fn;
bdi->congested_data = info;
bdi->capabilities |= BDI_CAP_CGROUP_WRITEBACK;
return 0;
}

Expand Down
16 changes: 13 additions & 3 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2730,6 +2730,9 @@ struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask)
btrfs_bio->csum = NULL;
btrfs_bio->csum_allocated = NULL;
btrfs_bio->end_io = NULL;
/* FIXME, put this into bio_clone_bioset */
if (bio->bi_css)
bio_associate_blkcg(new, bio->bi_css);
}
return new;
}
Expand Down Expand Up @@ -2790,6 +2793,7 @@ static int merge_bio(int rw, struct extent_io_tree *tree, struct page *page,
}

static int submit_extent_page(int rw, struct extent_io_tree *tree,
struct writeback_control *wbc,
struct page *page, sector_t sector,
size_t size, unsigned long offset,
struct block_device *bdev,
Expand Down Expand Up @@ -2826,6 +2830,8 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
}
bio = NULL;
} else {
if (wbc)
wbc_account_io(wbc, page, page_size);
return 0;
}
}
Expand All @@ -2841,6 +2847,10 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
bio_add_page(bio, page, page_size, offset);
bio->bi_end_io = end_io_func;
bio->bi_private = tree;
if (wbc) {
wbc_init_bio(wbc, bio);
wbc_account_io(wbc, page, page_size);
}

if (bio_ret)
*bio_ret = bio;
Expand Down Expand Up @@ -3051,7 +3061,7 @@ static int __do_readpage(struct extent_io_tree *tree,
}

pnr -= page->index;
ret = submit_extent_page(rw, tree, page,
ret = submit_extent_page(rw, tree, NULL, page,
sector, disk_io_size, pg_offset,
bdev, bio, pnr,
end_bio_extent_readpage, mirror_num,
Expand Down Expand Up @@ -3446,7 +3456,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
page->index, cur, end);
}

ret = submit_extent_page(write_flags, tree, page,
ret = submit_extent_page(write_flags, tree, wbc, page,
sector, iosize, pg_offset,
bdev, &epd->bio, max_nr,
end_bio_extent_writepage,
Expand Down Expand Up @@ -3749,7 +3759,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,

clear_page_dirty_for_io(p);
set_page_writeback(p);
ret = submit_extent_page(rw, tree, p, offset >> 9,
ret = submit_extent_page(rw, tree, wbc, p, offset >> 9,
PAGE_CACHE_SIZE, 0, bdev, &epd->bio,
-1, end_bio_extent_buffer_writepage,
0, epd->bio_flags, bio_flags);
Expand Down
6 changes: 5 additions & 1 deletion fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -7987,7 +7987,11 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,
u64 first_sector, gfp_t gfp_flags)
{
int nr_vecs = bio_get_nr_vecs(bdev);
return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags);
struct bio *bio;
bio = btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags);
if (bio)
bio_associate_current(bio);
return bio;
}

static inline int btrfs_lookup_and_bind_dio_csum(struct btrfs_root *root,
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ static int btrfs_fill_super(struct super_block *sb,
sb->s_flags |= MS_POSIXACL;
#endif
sb->s_flags |= MS_I_VERSION;
sb->s_iflags |= SB_I_CGROUPWB;
err = open_ctree(sb, fs_devices, (char *)data);
if (err) {
printk(KERN_ERR "BTRFS: open_ctree failed\n");
Expand Down
8 changes: 8 additions & 0 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5942,6 +5942,14 @@ static int breakup_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio,
if (!bio)
return -ENOMEM;

if (first_bio->bi_ioc) {
get_io_context_active(first_bio->bi_ioc);
bio->bi_ioc = first_bio->bi_ioc;
}
if (first_bio->bi_css) {
css_get(first_bio->bi_css);
bio->bi_css = first_bio->bi_css;
}
while (bvec <= (first_bio->bi_io_vec + first_bio->bi_vcnt - 1)) {
if (bio_add_page(bio, bvec->bv_page, bvec->bv_len,
bvec->bv_offset) < bvec->bv_len) {
Expand Down

0 comments on commit da2f0f7

Please sign in to comment.