Re: [PATCH] f2fs: implement cgroup writeback supprot

From: Chao Yu
Date: Mon Jan 08 2018 - 21:06:39 EST


On 2018/1/5 14:28, Yufen Yu wrote:
> Cgroup writeback requires explicit support from the filesystem.
> f2fs's data and node writeback IOs go through __write_data_page,
> which sets fio for submiting IOs. So, we add io_wbc for fio,
> associate bios with blkcg by invoking wbc_init_bio() and
> account IOs issuing by wbc_account_io().
> In addtion, f2fs_fill_super() is updated to set SB_I_CGROUPWB.
>
> Meta writeback IOs is left alone by this patch and will always be
> attributed to the root cgroup.
>
> The results show that f2fs can throttle writeback nicely for
> data writing and file creating.
>
> Signed-off-by: Yufen Yu <yuyufen@xxxxxxxxxx>
> ---
> fs/f2fs/data.c | 11 +++++++++--
> fs/f2fs/f2fs.h | 1 +
> fs/f2fs/node.c | 1 +
> fs/f2fs/super.c | 1 +
> 4 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 516fa0d..402df03 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -169,6 +169,7 @@ static bool __same_bdev(struct f2fs_sb_info *sbi,
> * Low-level block read/write IO operations.
> */
> static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr,
> + struct writeback_control *wbc,
> int npages, bool is_read)
> {
> struct bio *bio;
> @@ -178,6 +179,8 @@ static struct bio *__bio_alloc(struct f2fs_sb_info *sbi, block_t blk_addr,
> f2fs_target_device(sbi, blk_addr, bio);
> bio->bi_end_io = is_read ? f2fs_read_end_io : f2fs_write_end_io;
> bio->bi_private = is_read ? NULL : sbi;
> + if (wbc)
> + wbc_init_bio(wbc, bio);
>
> return bio;
> }
> @@ -373,7 +376,8 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
> f2fs_trace_ios(fio, 0);
>
> /* Allocate a new bio */
> - bio = __bio_alloc(fio->sbi, fio->new_blkaddr, 1, is_read_io(fio->op));
> + bio = __bio_alloc(fio->sbi, fio->new_blkaddr, fio->io_wbc,
> + 1, is_read_io(fio->op));
>
> if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
> bio_put(bio);
> @@ -435,7 +439,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
> dec_page_count(sbi, WB_DATA_TYPE(bio_page));
> goto out_fail;
> }
> - io->bio = __bio_alloc(sbi, fio->new_blkaddr,
> + io->bio = __bio_alloc(sbi, fio->new_blkaddr, fio->io_wbc,
> BIO_MAX_PAGES, false);
> io->fio = *fio;
> }
> @@ -443,6 +447,8 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
> if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) < PAGE_SIZE) {
> __submit_merged_bio(io);
> goto alloc_new;
> + } else if (fio->io_wbc) {
> + wbc_account_io(fio->io_wbc, bio_page, PAGE_SIZE);
> }

if (bio_add_page()) {
__submit_merged_bio();
goto alloc_new;
}

if (fio->io_wbc)
wbc_account_io(fio->io_wbc, bio_page, PAGE_SIZE);

Other part looks good to me.

Reviewed-by: Chao Yu <yuchao0@xxxxxxxxxx>

Thanks,

>
> io->last_block_in_bio = fio->new_blkaddr;
> @@ -1508,6 +1514,7 @@ static int __write_data_page(struct page *page, bool *submitted,
> .submitted = false,
> .need_lock = LOCK_RETRY,
> .io_type = io_type,
> + .io_wbc = wbc,
> };
>
> trace_f2fs_writepage(page, DATA);
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 6abf26c..4887dde 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -957,6 +957,7 @@ struct f2fs_io_info {
> int need_lock; /* indicate we need to lock cp_rwsem */
> bool in_list; /* indicate fio is in io_list */
> enum iostat_type io_type; /* io type */
> + struct writeback_control *io_wbc; /* writeback control */
> };
>
> #define is_read_io(rw) ((rw) == READ)
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index d332275..e4f8bb0 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -1336,6 +1336,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
> .encrypted_page = NULL,
> .submitted = false,
> .io_type = io_type,
> + .io_wbc = wbc,
> };
>
> trace_f2fs_writepage(page, NODE);
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 708155d..deeba98 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -2475,6 +2475,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
> sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
> (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0);
> memcpy(&sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid));
> + sb->s_iflags |= SB_I_CGROUPWB;
>
> /* init f2fs-specific super block info */
> sbi->valid_super_block = valid_super_block;
>