]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
f2fs: implement cgroup writeback support
authorYufen Yu <yuyufen@huawei.com>
Tue, 9 Jan 2018 11:33:39 +0000 (19:33 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 16 Jan 2018 23:40:01 +0000 (15:40 -0800)
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.

Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/node.c
fs/f2fs/super.c

index a023863ef27f0c5c06cd10b763ce644acd801e8b..304b899a6892fadac62073cf03ce727fa2dc6361 100644 (file)
@@ -170,6 +170,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;
@@ -179,6 +180,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;
 }
@@ -374,7 +377,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);
@@ -436,7 +440,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;
        }
@@ -446,6 +450,9 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
                goto alloc_new;
        }
 
+       if (fio->io_wbc)
+               wbc_account_io(fio->io_wbc, bio_page, PAGE_SIZE);
+
        io->last_block_in_bio = fio->new_blkaddr;
        f2fs_trace_ios(fio, 0);
 
@@ -1529,6 +1536,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);
index fdbaa8fcec2faa4846fbd3a325b96191254c9118..757c1ef742ea4f9519b71cd4908aa7f8eaeb8698 100644 (file)
@@ -961,6 +961,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)
index b495a543819c5245574291da1b0f18edd709b9a5..ea29314ca8a3a0f4b56bc70c1f67e7910285e4d8 100644 (file)
@@ -1335,6 +1335,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);
index 8b86a483ddd770430f2fb22c37f035807792d0f2..ec489b20544387253aa42abb109871281d9596a5 100644 (file)
@@ -2518,6 +2518,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;