cgroup, writeback, btrfs: make sure btrfs issues metadata IOs from the root cgroup
Subsystems (6)
Tejun Heo
maintainerPATCH v2 1/1 cgroup, writeback, btrfs: make sure btrfs issues metadata IOs from the root cgroup
Hello,
Changes from the last version are
* blkcg_root_css exported to fix build breakage on modular btrfs.
* Use ext4_should_journal_data() test instead of
EXT4_MOUNT_JOURNAL_DATA.
* Separated out create_bh_bio() and used it to implement submit_bh_blkcg_css() as suggested by Jan.
btrfs has different ways to issue metadata IOs and may end up issuing metadata or otherwise shared IOs from a non-root cgroup, which can lead to priority inversion and ineffective IO isolation.
This patchset makes sure that btrfs issues all metadata and shared IOs from the root cgroup by exempting btree_inodes from cgroup writeback and explicitly associating shared IOs with the root cgroup.
This patchset containst he following three patches
[PATCH 1/5] blkcg: export blkcg_root_css
[PATCH 2/5] cgroup, writeback: replace SB_I_CGROUPWB with per-inode [PATCH 3/5] buffer_head: separate out create_bh_bio() from [PATCH 4/5] cgroup, buffer_head: implement submit_bh_blkcg_css() [PATCH 5/5] btrfs: ensure that metadata and flush are issued from the
and is also available in the following git branch
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-cgroup-btrfs-metadata-v2
diffstat follows. Thanks.
block/blk-cgroup.c | 1 + fs/block_dev.c | 3 +-- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 6 +++++- fs/btrfs/super.c | 1 - fs/buffer.c | 42 ++++++++++++++++++++++++++++++++++-------- fs/ext2/inode.c | 3 ++- fs/ext2/super.c | 1 - fs/ext4/inode.c | 5 ++++- fs/ext4/super.c | 2 -- include/linux/backing-dev.h | 2 +- include/linux/buffer_head.h | 3 +++ include/linux/fs.h | 3 ++- 14 files changed, 58 insertions(+), 20 deletions(-)
--
tejun
Tejun Heo
maintainerPATCH 1/5 blkcg: export blkcg_root_css
Export blkcg_root_css so that filesystem modules can use it.
--- block/blk-cgroup.c | 1 + 1 file changed, 1 insertion(+)
block/blk-cgroup.c +1 -0
@@ -45,6 +45,7 @@ struct blkcg blkcg_root;EXPORT_SYMBOL_GPL (blkcg_root);struct cgroup_subsys_state *const blkcg_root_css = &blkcg_root.css; +EXPORT_SYMBOL_GPL (blkcg_root_css);static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS ];
Signature · 1 line
2.9.5
Re: [PATCH 1/5] blkcg: export blkcg_root_css
Quoted 3 lines · Tejun Heo
Export
blkcg_root_cssso that filesystem modules can use it.Signed-off-by Tejun Heo <[email protected]>
Looks good. You can add:
Honza
Quoted 19 lines
--- block/blk-cgroup.c | 1 + 1 file changed, 1 insertion(+)block/blk-cgroup.c +1
-0@@ -45,6 +45,7 @@ struct blkcg blkcg_root;EXPORT_SYMBOL_GPL (blkcg_root);struct cgroup_subsys_state *const blkcg_root_css = &blkcg_root.css; +EXPORT_SYMBOL_GPL (blkcg_root_css);static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS ];Signature · 1 line
2.9.5
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerPATCH 2/5 cgroup, writeback: replace SB_I_CGROUPWB with per-inode S_CGROUPWB
In reply to Tejun HeoCurrently, filesystem can indiate cgroup writeback support per superblock; however, depending on the filesystem, especially if inodes are used to carry metadata, it can be useful to indicate cgroup writeback support per inode.
This patch replaces the superblock flag SB_I_CGROUPWB with per-inode S_CGROUPWB, so that cgroup writeback can be enabled selectively.
* block_dev sets the new flag in bdget() when initializing new inode.
* ext2 sets the new flag in ext2_set_inode_flags().
* ext4 sets the new flag in ext4_set_inode_flags() if !ext4_should_journal_data(inode). This makes inodes whose data is journalled due to inode flags to bypass cgroup writeback. This behavior change is intended.
* btrfs sets the new flag in btrfs_update_iflags() function. Note that this automatically excludes btree_inode which doesn't use btrfs_update_iflags() during initialization. This behavior change is intended.
v2: Use ext4_should_journal_data() as suggested by Jan.
--- fs/block_dev.c | 3 +-- fs/btrfs/ioctl.c | 4 +++- fs/btrfs/super.c | 1 - fs/ext2/inode.c | 3 ++- fs/ext2/super.c | 1 - fs/ext4/inode.c | 5 ++++- fs/ext4/super.c | 2 -- include/linux/backing-dev.h | 2 +- include/linux/fs.h | 3 ++- 9 files changed, 13 insertions(+), 11 deletions(-)
fs/block_dev.c +1 -2
@@ -800,8 +800,6 @@ static struct dentry *bd_mount(struct file_system_type *fs_type, {struct dentry *dent; dent =mount_pseudo (fs_type,"bdev:" , &bdev_sops,NULL ,BDEVFS_MAGIC ); -if (!IS_ERR (dent)) - dent->d_sb->s_iflags |=SB_I_CGROUPWB ;return dent; }
@@ -893,6 +891,7 @@ struct block_device *bdget(dev_t dev) inode->i_mode =S_IFBLK ; inode->i_rdev = dev; inode->i_bdev = bdev; + inode->i_flags |=S_CGROUPWB ; inode->i_data.a_ops = &def_blk_aops;mapping_set_gfp_mask (&inode->i_data,GFP_USER );spin_lock (&bdev_lock);
fs/btrfs/ioctl.c +3 -1
@@ -150,9 +150,11 @@ void btrfs_update_iflags(struct inode *inode) new_fl |=S_NOATIME ;if (ip->flags &BTRFS_INODE_DIRSYNC ) new_fl |=S_DIRSYNC ; + new_fl |=S_CGROUPWB ;set_mask_bits (&inode->i_flags, -S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME |S_DIRSYNC , +S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME |S_DIRSYNC | +S_CGROUPWB , new_fl); }
fs/btrfs/super.c +0 -1
@@ -1136,7 +1136,6 @@ 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 =super_setup_bdi (sb);if (err) {
fs/ext2/inode.c +2 -1
@@ -1372,7 +1372,7 @@ void ext2_set_inode_flags(struct inode *inode)unsigned int flags =EXT2_I (inode)->i_flags; inode->i_flags &= ~(S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME | -S_DIRSYNC |S_DAX ); +S_DIRSYNC |S_DAX |S_CGROUPWB );if (flags &EXT2_SYNC_FL ) inode->i_flags |=S_SYNC ;if (flags &EXT2_APPEND_FL )
@@ -1385,6 +1385,7 @@ void ext2_set_inode_flags(struct inode *inode) inode->i_flags |=S_DIRSYNC ;if (test_opt (inode->i_sb,DAX ) &&S_ISREG (inode->i_mode)) inode->i_flags |=S_DAX ; + inode->i_flags |=S_CGROUPWB ; }struct inode *ext2_iget (struct super_block *sb,unsigned long ino)
fs/ext2/super.c +0 -1
@@ -922,7 +922,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) sb->s_flags = (sb->s_flags & ~MS_POSIXACL ) | ((EXT2_SB (sb)->s_mount_opt &EXT2_MOUNT_POSIX_ACL ) ?MS_POSIXACL :0 ); - sb->s_iflags |=SB_I_CGROUPWB ; if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV && (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
fs/ext4/inode.c +4 -1
@@ -4591,8 +4591,11 @@ void ext4_set_inode_flags(struct inode *inode) !ext4_should_journal_data(inode) && !ext4_has_inline_data(inode) && !ext4_encrypted_inode(inode)) new_fl |=S_DAX ; +if (!ext4_should_journal_data (inode)) + new_fl |=S_CGROUPWB ;inode_set_flags (inode, new_fl, -S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME |S_DIRSYNC |S_DAX ); +S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME |S_DIRSYNC |S_DAX | +S_CGROUPWB ); } static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
fs/ext4/super.c +0 -2
@@ -3620,8 +3620,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) }if (test_opt (sb,DELALLOC ))clear_opt (sb,DELALLOC ); - }else { - sb->s_iflags |=SB_I_CGROUPWB ; } sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
include/linux/backing-dev.h +1 -1
@@ -246,7 +246,7 @@ static inline bool inode_cgwb_enabled(struct inode *inode)cgroup_subsys_on_dfl (io_cgrp_subsys) &&bdi_cap_account_dirty (bdi) && (bdi->capabilities &BDI_CAP_CGROUP_WRITEBACK ) && - (inode->i_sb->s_iflags &SB_I_CGROUPWB ); +IS_CGROUPWB (inode); }/**
include/linux/fs.h +2 -1
@@ -1308,7 +1308,6 @@ extern int send_sigurg(struct fown_struct *fown);#define UMOUNT_UNUSED 0x80000000/* Flag guaranteed to be unused */ /* sb->s_iflags */ -#define SB_I_CGROUPWB 0x00000001/* cgroup-aware writeback enabled */ #define SB_I_NOEXEC 0x00000002/* Ignore executables on this fs */ #define SB_I_NODEV 0x00000004/* Ignore devices on this fs */
@@ -1853,6 +1852,7 @@ struct super_operations {#else #define S_DAX 0/* Make all the DAX code disappear */ #endif +#define S_CGROUPWB 16384/* Enable cgroup writeback for this inode */ /* * Note that nosuid etc flags are inode-specific: setting some file-system
@@ -1892,6 +1892,7 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags#define IS_AUTOMOUNT (inode) ((inode)->i_flags & S_AUTOMOUNT)#define IS_NOSEC (inode) ((inode)->i_flags & S_NOSEC)#define IS_DAX (inode) ((inode)->i_flags & S_DAX) +#define IS_CGROUPWB (inode) ((inode)->i_flags & S_CGROUPWB)#define IS_WHITEOUT (inode) (S_ISCHR(inode->i_mode) && \ (inode)->i_rdev == WHITEOUT_DEV)
Signature · 1 line
2.9.5
Tejun Heo
maintainerPATCH 3/5 buffer_head: separate out create_bh_bio() from submit_bh_wbc()
In reply to Tejun Heosubmit_bh_wbc() creates a bio matching the specific @bh and submits it at the end. This patch separates out the bio creation part to its own function, create_bh_bio(), and reimplement submit_bh[_wbc]() using the function.
As bio can now be manipulated before submitted, we can move out @wbc handling into submit_bh_wbc() and similarly this will make adding more submit_bh variants straight-forward.
This patch is pure refactoring and doesn't cause any functional changes.
--- fs/buffer.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-)
fs/buffer.c +22 -8
@@ -3086,8 +3086,8 @@ void guard_bio_eod(int op, struct bio *bio) } } -static int submit_bh_wbc (int op,int op_flags,struct buffer_head *bh, -enum rw_hint write_hint,struct writeback_control *wbc) +struct bio *create_bh_bio (int op,int op_flags,struct buffer_head *bh, +enum rw_hint write_hint) {struct bio *bio;
@@ -3109,11 +3109,6 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,*/ bio =bio_alloc (GFP_NOIO ,1 ); -if (wbc) { -wbc_init_bio (wbc, bio); -wbc_account_io (wbc, bh->b_page, bh->b_size); - } - bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >>9 );bio_set_dev (bio, bh->b_bdev); bio->bi_write_hint = write_hint;
@@ -3133,13 +3128,32 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, op_flags |=REQ_PRIO ;bio_set_op_attrs (bio, op, op_flags); +return bio; +} + +static int submit_bh_wbc (int op,int op_flags,struct buffer_head *bh, +enum rw_hint write_hint,struct writeback_control *wbc) +{ +struct bio *bio; + + bio =create_bh_bio (op, op_flags, bh, write_hint); + +if (wbc) { +wbc_init_bio (wbc, bio); +wbc_account_io (wbc, bh->b_page, bh->b_size); + } +submit_bio (bio);return 0 ; }int submit_bh (int op,int op_flags,struct buffer_head *bh) { -return submit_bh_wbc (op, op_flags, bh,0 ,NULL ); +struct bio *bio; + + bio =create_bh_bio (op, op_flags, bh,0 ); +submit_bio (bio); +return 0 ; }EXPORT_SYMBOL (submit_bh);
Signature · 1 line
2.9.5
Re: [PATCH 3/5] buffer_head: separate out create_bh_bio() from submit_bh_wbc()
Quoted 9 lines · Tejun Heo
submit_bh_wbc()creates a bio matching the specific @bh and submits it at the end. This patch separates out the bio creation part to its own function,create_bh_bio(), and reimplement submit_bh[_wbc]() using the function.As bio can now be manipulated before submitted, we can move out @wbc handling into
submit_bh_wbc()and similarly this will make adding moresubmit_bhvariants straight-forward.
Quoted 5 lines
This patch is pure refactoring and doesn't cause any functional changes.
Signed-off-by Tejun Heo <[email protected]>Suggested-by Jan Kara <[email protected]>
Looks good to me. You can add:
Honza
Quoted 68 lines
--- fs/buffer.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-)fs/buffer.c +22
-8@@ -3086,8 +3086,8 @@ void guard_bio_eod(int op, struct bio *bio) } } -static int submit_bh_wbc (int op,int op_flags,struct buffer_head *bh, -enum rw_hint write_hint,struct writeback_control *wbc) +struct bio *create_bh_bio (int op,int op_flags,struct buffer_head *bh, +enum rw_hint write_hint) {struct bio *bio;@@ -3109,11 +3109,6 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,*/ bio =bio_alloc (GFP_NOIO ,1 ); -if (wbc) { -wbc_init_bio (wbc, bio); -wbc_account_io (wbc, bh->b_page, bh->b_size); - } - bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >>9 );bio_set_dev (bio, bh->b_bdev); bio->bi_write_hint = write_hint;@@ -3133,13 +3128,32 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, op_flags |=REQ_PRIO ;bio_set_op_attrs (bio, op, op_flags); +return bio; +} + +static int submit_bh_wbc (int op,int op_flags,struct buffer_head *bh, +enum rw_hint write_hint,struct writeback_control *wbc) +{ +struct bio *bio; + + bio =create_bh_bio (op, op_flags, bh, write_hint); + +if (wbc) { +wbc_init_bio (wbc, bio); +wbc_account_io (wbc, bh->b_page, bh->b_size); + } +submit_bio (bio);return 0 ; }int submit_bh (int op,int op_flags,struct buffer_head *bh) { -return submit_bh_wbc (op, op_flags, bh,0 ,NULL ); +struct bio *bio; + + bio =create_bh_bio (op, op_flags, bh,0 ); +submit_bio (bio); +return 0 ; }EXPORT_SYMBOL (submit_bh);Signature · 1 line
2.9.5
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerPATCH 4/5 cgroup, buffer_head: implement submit_bh_blkcg_css()
In reply to Tejun HeoImplement submit_bh_blkcg_css() which will be used to override cgroup membership on specific buffer_heads.
v2: Reimplemented using create_bh_bio() as suggested by Jan.
--- fs/buffer.c | 12 ++++++++++++ include/linux/buffer_head.h | 3 +++ 2 files changed, 15 insertions(+)
fs/buffer.c +12 -0
@@ -3147,6 +3147,18 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,return 0 ; } +int submit_bh_blkcg_css (int op,int op_flags,struct buffer_head *bh, +struct cgroup_subsys_state *blkcg_css) +{ +struct bio *bio; + + bio =create_bh_bio (op, op_flags, bh,0 ); +bio_associate_blkcg (bio, blkcg_css); +submit_bio (bio); +return 0 ; +} +EXPORT_SYMBOL (submit_bh_blkcg_css); +int submit_bh (int op,int op_flags,struct buffer_head *bh) {struct bio *bio;
include/linux/buffer_head.h +3 -0
@@ -13,6 +13,7 @@#include <linux/pagemap.h> #include <linux/wait.h> #include <linux/atomic.h> +#include <linux/cgroup.h> #ifdef CONFIG_BLOCK
@@ -197,6 +198,8 @@ void ll_rw_block(int, int, int, struct buffer_head * bh[]);int sync_dirty_buffer (struct buffer_head *bh);int __sync_dirty_buffer (struct buffer_head *bh,int op_flags);void write_dirty_buffer (struct buffer_head *bh,int op_flags); +int submit_bh_blkcg_css (int op,int op_flags,struct buffer_head *bh, +struct cgroup_subsys_state *blkcg_css);int submit_bh (int ,int ,struct buffer_head *);void write_boundary_block (struct block_device *bdev,sector_t bblock,unsigned blocksize);
Signature · 1 line
2.9.5
Re: [PATCH 4/5] cgroup, buffer_head: implement submit_bh_blkcg_css()
Quoted 8 lines · Tejun Heo
Implement
submit_bh_blkcg_css()which will be used to override cgroup membership on specificbuffer_heads.v2: Reimplemented using
create_bh_bio()as suggested by Jan.Signed-off-by Tejun Heo <[email protected]>Cc Jan Kara <[email protected]>Cc Jens Axboe <[email protected]>
Looks good. You can add:
Honza
Quoted 52 lines
--- fs/buffer.c | 12 ++++++++++++ include/linux/buffer_head.h | 3 +++ 2 files changed, 15 insertions(+)fs/buffer.c +12
-0@@ -3147,6 +3147,18 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,return 0 ; } +int submit_bh_blkcg_css (int op,int op_flags,struct buffer_head *bh, +struct cgroup_subsys_state *blkcg_css) +{ +struct bio *bio; + + bio =create_bh_bio (op, op_flags, bh,0 ); +bio_associate_blkcg (bio, blkcg_css); +submit_bio (bio); +return 0 ; +} +EXPORT_SYMBOL (submit_bh_blkcg_css); +int submit_bh (int op,int op_flags,struct buffer_head *bh) {struct bio *bio;include/linux/buffer_head.h +3
-0@@ -13,6 +13,7 @@#include <linux/pagemap.h> #include <linux/wait.h> #include <linux/atomic.h> +#include <linux/cgroup.h> #ifdef CONFIG_BLOCK @@ -197,6 +198,8 @@ void ll_rw_block(int, int, int, struct buffer_head * bh[]);int sync_dirty_buffer (struct buffer_head *bh);int __sync_dirty_buffer (struct buffer_head *bh,int op_flags);void write_dirty_buffer (struct buffer_head *bh,int op_flags); +int submit_bh_blkcg_css (int op,int op_flags,struct buffer_head *bh, +struct cgroup_subsys_state *blkcg_css);int submit_bh (int ,int ,struct buffer_head *);void write_boundary_block (struct block_device *bdev,sector_t bblock,unsigned blocksize);Signature · 1 line
2.9.5
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerPATCH 5/5 btrfs: ensure that metadata and flush are issued from the root cgroup
In reply to Tejun HeoIssuing metdata or otherwise shared IOs from !root cgroup can lead to priority inversion. This patch ensures that those IOs are always issued from the root cgroup.
This patch updates btrfs_update_iflags() to not set S_CGROUPWB on btree_inodes. This isn't strictly necessary as those inodes don't call the function during init; however, this serves as documentation and prevents possible future mistakes. If this isn't desirable, please feel free to drop the section.
--- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)
fs/btrfs/check-integrity.c +1 -1
@@ -2741,7 +2741,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh)struct btrfsic_dev_state *dev_state;if (!btrfsic_is_initialized) -return submit_bh (op, op_flags, bh); +return submit_bh_blkcg_css (op, op_flags, blkcg_root_css);mutex_lock (&btrfsic_mutex);/* since btrfsic_submit_bh() might also be called before
fs/btrfs/disk-io.c +4 -0
@@ -1025,6 +1025,8 @@ static blk_status_t btree_submit_bio_hook(void *private_data, struct bio *bio,int async =check_async_write (bio_flags);blk_status_t ret; +bio_associate_blkcg (bio, blkcg_root_css); +if (bio_op (bio) !=REQ_OP_WRITE ) {/* * called for a read, do the setup so that checksum validation
@@ -3512,6 +3514,8 @@ static void write_dev_flush(struct btrfs_device *device)return ;bio_reset (bio); +bio_associate_blkcg (bio, blkcg_root_css); + bio->bi_end_io = btrfs_end_empty_barrier;bio_set_dev (bio, device->bdev); bio->bi_opf =REQ_OP_WRITE |REQ_SYNC |REQ_PREFLUSH ;
fs/btrfs/ioctl.c +3 -1
@@ -150,7 +150,9 @@ void btrfs_update_iflags(struct inode *inode) new_fl |=S_NOATIME ;if (ip->flags &BTRFS_INODE_DIRSYNC ) new_fl |=S_DIRSYNC ; - new_fl |=S_CGROUPWB ; +/* btree_inodes are always in the root cgroup */ +if (btrfs_ino (ip) !=BTRFS_BTREE_INODE_OBJECTID ) + new_fl |=S_CGROUPWB ; set_mask_bits(&inode->i_flags, S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC |
Signature · 1 line
2.9.5
Tejun Heo
maintainerPATCH v2 5/5 btrfs: ensure that metadata and flush are issued from the root cgroup
Quoted 1 line
From
3bbed8c7747739cda48f592f165e8839da076a3aMon Sep 17 00:00:00 2001
Issuing metdata or otherwise shared IOs from !root cgroup can lead to priority inversion. This patch ensures that those IOs are always issued from the root cgroup.
This patch updates btrfs_update_iflags() to not set S_CGROUPWB on btree_inodes. This isn't strictly necessary as those inodes don't call the function during init; however, this serves as documentation and prevents possible future mistakes. If this isn't desirable, please feel free to drop the section.
v2: Fixed missing @bh in submit_bh_blkcg_css() call.
--- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)
fs/btrfs/check-integrity.c +1 -1
@@ -2741,7 +2741,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh)struct btrfsic_dev_state *dev_state;if (!btrfsic_is_initialized) -return submit_bh (op, op_flags, bh); +return submit_bh_blkcg_css (op, op_flags, bh, blkcg_root_css);mutex_lock (&btrfsic_mutex);/* since btrfsic_submit_bh() might also be called before
fs/btrfs/disk-io.c +4 -0
@@ -1025,6 +1025,8 @@ static blk_status_t btree_submit_bio_hook(void *private_data, struct bio *bio,int async =check_async_write (bio_flags);blk_status_t ret; +bio_associate_blkcg (bio, blkcg_root_css); +if (bio_op (bio) !=REQ_OP_WRITE ) {/* * called for a read, do the setup so that checksum validation
@@ -3512,6 +3514,8 @@ static void write_dev_flush(struct btrfs_device *device)return ;bio_reset (bio); +bio_associate_blkcg (bio, blkcg_root_css); + bio->bi_end_io = btrfs_end_empty_barrier;bio_set_dev (bio, device->bdev); bio->bi_opf =REQ_OP_WRITE |REQ_SYNC |REQ_PREFLUSH ;
fs/btrfs/ioctl.c +3 -1
@@ -150,7 +150,9 @@ void btrfs_update_iflags(struct inode *inode) new_fl |=S_NOATIME ;if (ip->flags &BTRFS_INODE_DIRSYNC ) new_fl |=S_DIRSYNC ; - new_fl |=S_CGROUPWB ; +/* btree_inodes are always in the root cgroup */ +if (btrfs_ino (ip) !=BTRFS_BTREE_INODE_OBJECTID ) + new_fl |=S_CGROUPWB ; set_mask_bits(&inode->i_flags, S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC |
Signature · 1 line
2.9.5
Re: [PATCH v2 5/5] btrfs: ensure that metadata and flush are issued from the root cgroup
Quoted 6 lines · Tejun Heo
From
3bbed8c7747739cda48f592f165e8839da076a3aMon Sep 17 00:00:00 2001Issuing metdata or otherwise shared IOs from !root cgroup can lead to priority inversion. This patch ensures that those IOs are always issued from the root cgroup.
Quoted 8 lines
This patch updates
btrfs_update_iflags()to not setS_CGROUPWBonbtree_inodes. This isn't strictly necessary as those inodes don't call the function during init; however, this serves as documentation and prevents possible future mistakes. If this isn't desirable, please feel free to drop the section.v2: Fixed missing @bh in
submit_bh_blkcg_css()call.
Looks good.
-liubo
Quoted 66 lines
Signed-off-by Tejun Heo <[email protected]>Cc Chris Mason <[email protected]>Cc Josef Bacik <[email protected]>--- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)fs/btrfs/check-integrity.c +1
-1@@ -2741,7 +2741,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh)struct btrfsic_dev_state *dev_state;if (!btrfsic_is_initialized) -return submit_bh (op, op_flags, bh); +return submit_bh_blkcg_css (op, op_flags, bh, blkcg_root_css);mutex_lock (&btrfsic_mutex);/* since btrfsic_submit_bh() might also be called before fs/btrfs/disk-io.c +4
-0@@ -1025,6 +1025,8 @@ static blk_status_t btree_submit_bio_hook(void *private_data, struct bio *bio,int async =check_async_write (bio_flags);blk_status_t ret; +bio_associate_blkcg (bio, blkcg_root_css); +if (bio_op (bio) !=REQ_OP_WRITE ) {/* * called for a read, do the setup so that checksum validation @@ -3512,6 +3514,8 @@ static void write_dev_flush(struct btrfs_device *device)return ;bio_reset (bio); +bio_associate_blkcg (bio, blkcg_root_css); + bio->bi_end_io = btrfs_end_empty_barrier;bio_set_dev (bio, device->bdev); bio->bi_opf =REQ_OP_WRITE |REQ_SYNC |REQ_PREFLUSH ;fs/btrfs/ioctl.c +3
-1@@ -150,7 +150,9 @@ void btrfs_update_iflags(struct inode *inode) new_fl |=S_NOATIME ;if (ip->flags &BTRFS_INODE_DIRSYNC ) new_fl |=S_DIRSYNC ; - new_fl |=S_CGROUPWB ; +/* btree_inodes are always in the root cgroup */ +if (btrfs_ino (ip) !=BTRFS_BTREE_INODE_OBJECTID ) + new_fl |=S_CGROUPWB ; set_mask_bits(&inode->i_flags, S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC |Signature · 6 lines
2.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/5] btrfs: ensure that metadata and flush are issued from the root cgroup
In reply to Tejun HeoQuoted 8 lines · Tejun Heo
Quoted 1 line
From
3bbed8c7747739cda48f592f165e8839da076a3aMon Sep 17 00:00:00 2001Issuing metdata or otherwise shared IOs from !root cgroup can lead to priority inversion. This patch ensures that those IOs are always issued from the root cgroup.
This patch updates
btrfs_update_iflags()to not setS_CGROUPWBonbtree_inodes.
The 'btree_inode' is only one, with inode number 1, and represents all the metadata, so I don't understand what it means in plural.
Quoted 56 lines
This isn't strictly necessary as those inodes don't
call the function during init; however, this serves as documentation and prevents possible future mistakes. If this isn't desirable, please feel free to drop the section.v2: Fixed missing @bh in
submit_bh_blkcg_css()call.Signed-off-by Tejun Heo <[email protected]>Cc Chris Mason <[email protected]>Cc Josef Bacik <[email protected]>--- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)fs/btrfs/check-integrity.c +1
-1@@ -2741,7 +2741,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh)struct btrfsic_dev_state *dev_state;if (!btrfsic_is_initialized) -return submit_bh (op, op_flags, bh); +return submit_bh_blkcg_css (op, op_flags, bh, blkcg_root_css);mutex_lock (&btrfsic_mutex);/* since btrfsic_submit_bh() might also be called before fs/btrfs/disk-io.c +4
-0@@ -1025,6 +1025,8 @@ static blk_status_t btree_submit_bio_hook(void *private_data, struct bio *bio,int async =check_async_write (bio_flags);blk_status_t ret; +bio_associate_blkcg (bio, blkcg_root_css); +if (bio_op (bio) !=REQ_OP_WRITE ) {/* * called for a read, do the setup so that checksum validation @@ -3512,6 +3514,8 @@ static void write_dev_flush(struct btrfs_device *device)return ;bio_reset (bio); +bio_associate_blkcg (bio, blkcg_root_css); + bio->bi_end_io = btrfs_end_empty_barrier;bio_set_dev (bio, device->bdev); bio->bi_opf =REQ_OP_WRITE |REQ_SYNC |REQ_PREFLUSH ;fs/btrfs/ioctl.c +0
-0
fs/btrfs/ioctl.c void btrfs_update_iflags(struct inode *inode) · line 155
Quoted 7 lines
fs/btrfs/ioctl.c +3
-1@@ -150,7 +150,9 @@ void btrfs_update_iflags(struct inode *inode) new_fl |=S_NOATIME ;if (ip->flags &BTRFS_INODE_DIRSYNC ) new_fl |=S_DIRSYNC ; - new_fl |=S_CGROUPWB ; +/* btree_inodes are always in the root cgroup */ +if (btrfs_ino (ip) !=BTRFS_BTREE_INODE_OBJECTID ) + new_fl |=S_CGROUPWB ;
The comment is useful, but the condition will be always true, so I don't see the point.
/* * The btree_inode will be always in the root cgroup. The cgroup * writeback can be enabled on regular inodes selectively. */ new_fl |= S_CGROUPWB;
is IMHO enough, based on my reading of patch 2/5 changelog.
Quoted 3 lines
fs/btrfs/ioctl.c +0
-0set_mask_bits(&inode->i_flags, S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC |
Tejun Heo
maintainerRe: [PATCH v2 5/5] btrfs: ensure that metadata and flush are issued from the root cgroup
Quoted 10 lines · David Sterba
The comment is useful, but the condition will be always true, so I don't see the point.
/* * The btree_inode will be always in the root cgroup. The cgroup * writeback can be enabled on regular inodes selectively. */ new_fl |= S_CGROUPWB;is IMHO enough, based on my reading of patch 2/5 changelog.
Will update accordingly.
Thanks.
Signature · 1 line
tejun
Tejun Heo
maintainerPATCH v3 5/5 btrfs: ensure that metadata and flush are issued from the root cgroup
In reply to David SterbaIssuing metdata or otherwise shared IOs from !root cgroup can lead to priority inversion. This patch ensures that those IOs are always issued from the root cgroup.
v3: Dropped unnecessary btree_inode handling as suggested by David
Sterba.
v2: Fixed missing @bh in submit_bh_blkcg_css() call.
--- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-)
fs/btrfs/check-integrity.c +1 -1
@@ -2741,7 +2741,7 @@ int btrfsic_submit_bh(int op, int op_flastruct btrfsic_dev_state *dev_state;if (!btrfsic_is_initialized) -return submit_bh (op, op_flags, bh); +return submit_bh_blkcg_css (op, op_flags, bh, blkcg_root_css);mutex_lock (&btrfsic_mutex);/* since btrfsic_submit_bh() might also be called before
fs/btrfs/disk-io.c +4 -0
@@ -1025,6 +1025,8 @@ static blk_status_t btree_submit_bio_hooint async =check_async_write (bio_flags);blk_status_t ret; +bio_associate_blkcg (bio, blkcg_root_css); +if (bio_op (bio) !=REQ_OP_WRITE ) {/* * called for a read, do the setup so that checksum validation
@@ -3512,6 +3514,8 @@ static void write_dev_flush(struct btrfsreturn ;bio_reset (bio); +bio_associate_blkcg (bio, blkcg_root_css); + bio->bi_end_io = btrfs_end_empty_barrier;bio_set_dev (bio, device->bdev); bio->bi_opf =REQ_OP_WRITE |REQ_SYNC |REQ_PREFLUSH ;
fs/btrfs/ioctl.c +4 -0
@@ -150,6 +150,10 @@ void btrfs_update_iflags(struct inode *i new_fl |=S_NOATIME ;if (ip->flags &BTRFS_INODE_DIRSYNC ) new_fl |=S_DIRSYNC ; +/* +* The btree_inode will be always in the root cgroup. The cgroup +* writeback can be enabled on regular inodes selectively. +*/ new_fl |=S_CGROUPWB ; set_mask_bits(&inode->i_flags,
Re: [PATCH v3 5/5] btrfs: ensure that metadata and flush are issued from the root cgroup
Quoted 4 lines · Tejun Heo
Issuing metdata or otherwise shared IOs from !root cgroup can lead to priority inversion. This patch ensures that those IOs are always issued from the root cgroup.
Quoted 8 lines
v3: Dropped unnecessary
btree_inodehandling as suggested by David
Sterba.v2: Fixed missing @bh in
submit_bh_blkcg_css()call.Signed-off-by Tejun Heo <[email protected]>Reviewed-by Liu Bo <[email protected]>Cc David Sterba <[email protected]>
Jan Kara
reviewerHi Tejun,
What has happened with this patch set?
Honza
Quoted 50 lines · Tejun Heo
Changes from the last version are
*
blkcg_root_cssexported to fix build breakage on modular btrfs.* Use
ext4_should_journal_data()test instead of
EXT4_MOUNT_JOURNAL_DATA.* Separated out
create_bh_bio()and used it to implementsubmit_bh_blkcg_css()as suggested by Jan.btrfs has different ways to issue metadata IOs and may end up issuing metadata or otherwise shared IOs from a non-root cgroup, which can lead to priority inversion and ineffective IO isolation.
This patchset makes sure that btrfs issues all metadata and shared IOs from the root cgroup by exempting
btree_inodesfrom cgroup writeback and explicitly associating shared IOs with the root cgroup.This patchset containst he following three patches
[PATCH 1/5] blkcg: export
blkcg_root_css
[PATCH 2/5] cgroup, writeback: replaceSB_I_CGROUPWBwith per-inode [PATCH 3/5]buffer_head: separate outcreate_bh_bio()from [PATCH 4/5] cgroup,buffer_head: implementsubmit_bh_blkcg_css()[PATCH 5/5] btrfs: ensure that metadata and flush are issued from theand is also available in the following git branch
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.gitreview-cgroup-btrfs-metadata-v2diffstat follows. Thanks.
block/blk-cgroup.c | 1 + fs/block_dev.c | 3 +-- fs/btrfs/check-integrity.c | 2 +- fs/btrfs/disk-io.c | 4 ++++ fs/btrfs/ioctl.c | 6 +++++- fs/btrfs/super.c | 1 - fs/buffer.c | 42 ++++++++++++++++++++++++++++++++++-------- fs/ext2/inode.c | 3 ++- fs/ext2/super.c | 1 - fs/ext4/inode.c | 5 ++++- fs/ext4/super.c | 2 -- include/linux/backing-dev.h | 2 +- include/linux/buffer_head.h | 3 +++ include/linux/fs.h | 3 ++- 14 files changed, 58 insertions(+), 20 deletions(-)--
tejun
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Tejun Heo
maintainerHello,
Quoted 1 line · Jan Kara
What has happened with this patch set?
No idea. cc'ing Chris directly. Chris, if the patchset looks good, can you please route them through the btrfs tree?
Thanks.
Signature · 1 line
tejun
Tejun Heo
maintainerQuoted 7 lines · Tejun Heo
Hello,
Quoted 1 line · Jan Kara
What has happened with this patch set?
No idea. cc'ing Chris directly. Chris, if the patchset looks good, can you please route them through the btrfs tree?
lol looking at the patchset again, I'm not sure that's obviously the right tree. It can either be cgroup, block or btrfs. If no one objects, I'll just route them through cgroup.
Thanks.
Signature · 1 line
tejun
Quoted 4 lines · Tejun Heo
Quoted 3 lines · Tejun Heo
Hello,
On Wed, Nov 29, 2017 at 05:56:08PM +0100, Jan Kara wrote:
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
What has happened with this patch set?
No idea. cc'ing Chris directly. Chris, if the patchset looks good, can you please route them through the btrfs tree?
lol looking at the patchset again, I'm not sure that's obviously the right tree. It can either be cgroup, block or btrfs. If no one objects, I'll just route them through cgroup.
We'll have to coordinate a bit during the next merge window but I don't have a problem with these going in through cgroup. Dave does this sound good to you?
I'd like to include my patch to do all crcs inline (instead of handing off to helper threads) when io controls are in place. By the merge window we should have some good data on how much it's all helping.
-chris
Quoted 10 lines · Chris Mason
Quoted 9 lines · Tejun Heo
Quoted 7 lines · Tejun Heo
Hello,
Quoted 1 line · Jan Kara
What has happened with this patch set?
No idea. cc'ing Chris directly. Chris, if the patchset looks good, can you please route them through the btrfs tree?
Quoted 7 lines
Quoted 3 lines
lol looking at the patchset again, I'm not sure that's obviously the right tree. It can either be cgroup, block or btrfs. If no one objects, I'll just route them through cgroup.
We'll have to coordinate a bit during the next merge window but I don't have a problem with these going in through cgroup. Dave does this sound good to you?
There are only minor changes to btrfs code so cgroup tree would be better.
Quoted 3 lines
I'd like to include my patch to do all crcs inline (instead of handing off to helper threads) when io controls are in place. By the merge window we should have some good data on how much it's all helping.
Are there any problems in sight if the inline crc and cgroup chnanges go separately? I assume there's a runtime dependency, not a code dependency, so it could be sorted by the right merge order.
Quoted 22 lines · David Sterba
Quoted 10 lines · Chris Mason
Quoted 9 lines · Tejun Heo
Quoted 7 lines · Tejun Heo
Hello,
Quoted 1 line · Jan Kara
What has happened with this patch set?
No idea. cc'ing Chris directly. Chris, if the patchset looks good, can you please route them through the btrfs tree?
Quoted 7 lines
Quoted 3 lines
lol looking at the patchset again, I'm not sure that's obviously the right tree. It can either be cgroup, block or btrfs. If no one objects, I'll just route them through cgroup.
We'll have to coordinate a bit during the next merge window but I don't have a problem with these going in through cgroup. Dave does this sound good to you?
There are only minor changes to btrfs code so cgroup tree would be better.
Quoted 8 lines
Quoted 3 lines
I'd like to include my patch to do all crcs inline (instead of handing off to helper threads) when io controls are in place. By the merge window we should have some good data on how much it's all helping.
Are there any problems in sight if the inline crc and cgroup chnanges go separately? I assume there's a runtime dependency, not a code dependency, so it could be sorted by the right merge order.
The feature is just more useful with the inline crcs. Without them we end up with kworkers doing both high and low prio submissions and it all boils down to the speed of the lowest priority.
-chris
Jan Kara
reviewerQuoted 10 lines · Chris Mason
Quoted 9 lines · Tejun Heo
Quoted 7 lines · Tejun Heo
Hello,
Quoted 1 line · Jan Kara
What has happened with this patch set?
No idea. cc'ing Chris directly. Chris, if the patchset looks good, can you please route them through the btrfs tree?
Quoted 7 lines
Quoted 3 lines
lol looking at the patchset again, I'm not sure that's obviously the right tree. It can either be cgroup, block or btrfs. If no one objects, I'll just route them through cgroup.
We'll have to coordinate a bit during the next merge window but I don't have a problem with these going in through cgroup. Dave does this sound good to you?
Also I was wondering about another thing: How does this play with Josef's series for metadata writeback (Metadata specific accouting and dirty writeout)? Would the per-inode selection of cgroup writeback still be needed when Josef's series is applied since metadata writeback then won't be associated with any particular mapping anymore?
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR