diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 4047278169bff3cfc05de5a2ed7f45b30a22d2de..562c9362e7d5a10be11274c943ac0a29ae2d55c4 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -150,6 +150,7 @@ CONFIG_MEMCG_MEMFS_INFO=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_V1_WRITEBACK=y +CONFIG_CGROUP_V1_BIND_BLKCG_MEMCG=y CONFIG_CGROUP_SCHED=y CONFIG_QOS_SCHED=y # CONFIG_QOS_SCHED_SMT_EXPELLER is not set diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 686e5cdfc80196ac2d0c01e48b51df5bc63b1634..6d1599e2f879f1d327e4be56de8bd38acbaaa270 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -157,6 +157,7 @@ CONFIG_MEMCG_MEMFS_INFO=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_V1_WRITEBACK=y +CONFIG_CGROUP_V1_BIND_BLKCG_MEMCG=y CONFIG_CGROUP_SCHED=y CONFIG_QOS_SCHED=y # CONFIG_QOS_SCHED_SMT_EXPELLER is not set diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index e598848edcee46562068e6565012b1e6c6880971..a689a21abe1002cb4dc314cf16ef7fab72ec0bbf 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -359,6 +359,10 @@ static inline void unlocked_inode_to_wb_end(struct inode *inode, rcu_read_unlock(); } + +void bind_memcg_blkcg_link(struct cgroup_subsys *ss, + struct css_set *cset); + #else /* CONFIG_CGROUP_WRITEBACK */ static inline bool inode_cgwb_enabled(struct inode *inode) @@ -411,6 +415,11 @@ static inline int inode_congested(struct inode *inode, int cong_bits) return wb_congested(&inode_to_bdi(inode)->wb, cong_bits); } +static inline void bind_memcg_blkcg_link(struct cgroup_subsys *ss, + struct css_set *cset) +{ +} + #endif /* CONFIG_CGROUP_WRITEBACK */ static inline int inode_read_congested(struct inode *inode) diff --git a/init/Kconfig b/init/Kconfig index 2eb3f376ff4fc0a09490cde8fcc1eb803be0f6a0..28d29bb59a918944c72356849e0ca96c64caabe4 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -961,6 +961,11 @@ config CGROUP_V1_WRITEBACK depends on CGROUP_WRITEBACK default n +config CGROUP_V1_BIND_BLKCG_MEMCG + bool "Add switches to bind memcg and blkcg" + depends on CGROUP_V1_WRITEBACK + default n + menuconfig CGROUP_SCHED bool "CPU controller" default n diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 262688aa2b7f11b20a252b950720d7653b57ec7c..2a7bcb2d09c5518dd3cf0eaf93955fc88d8becbf 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -82,6 +82,12 @@ DEFINE_MUTEX(cgroup_mutex); DEFINE_SPINLOCK(css_set_lock); +#ifdef CONFIG_CGROUP_V1_BIND_BLKCG_MEMCG +int sysctl_bind_memcg_blkcg_enable = 1; +#else +int sysctl_bind_memcg_blkcg_enable; +#endif + #ifdef CONFIG_PROVE_RCU EXPORT_SYMBOL_GPL(cgroup_mutex); EXPORT_SYMBOL_GPL(css_set_lock); @@ -2557,6 +2563,10 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx) tset->ssid = ssid; ss->attach(tset); } + if (sysctl_bind_memcg_blkcg_enable) { + list_for_each_entry(cset, &tset->dst_csets, mg_node) + bind_memcg_blkcg_link(ss, cset); + } } while_each_subsys_mask(); } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index d290ba2d8fee8b01ad66fdc3767e3d06bf6e2473..590993539ec082ef9518463836e7d073e8b8d5db 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1687,6 +1687,9 @@ int proc_do_static_key(struct ctl_table *table, int write, return ret; } +#ifdef CONFIG_CGROUP_V1_BIND_BLKCG_MEMCG +extern int sysctl_bind_memcg_blkcg_enable; +#endif static struct ctl_table kern_table[] = { { .procname = "sched_child_runs_first", @@ -1869,6 +1872,17 @@ static struct ctl_table kern_table[] = { .extra2 = SYSCTL_ONE, }, #endif +#ifdef CONFIG_CGROUP_V1_BIND_BLKCG_MEMCG + { + .procname = "bind_memcg_blkcg_enable", + .data = &sysctl_bind_memcg_blkcg_enable, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, +#endif #ifdef CONFIG_CFS_BANDWIDTH { .procname = "sched_cfs_bandwidth_slice_us", diff --git a/mm/backing-dev.c b/mm/backing-dev.c index fa2e26826150306e2d13872efbf1064c8afa5554..26d16d82dafc7273c24a51028f80e2c31006ff9c 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -16,7 +16,7 @@ struct backing_dev_info noop_backing_dev_info; EXPORT_SYMBOL_GPL(noop_backing_dev_info); - +extern struct mutex cgroup_mutex; static struct class *bdi_class; static const char *bdi_unknown_name = "(unknown)"; @@ -370,6 +370,40 @@ static void wb_exit(struct bdi_writeback *wb) #ifdef CONFIG_CGROUP_WRITEBACK #include +void bind_memcg_blkcg_link(struct cgroup_subsys *ss, + struct css_set *cset) +{ + struct cgroup_subsys_state *blkcg_css; + struct cgroup_subsys_state *memcg_css; + + if (!cgroup1_writeback_enabled()) + return; + if (ss->id != io_cgrp_id && ss->id != memory_cgrp_id) + return; + memcg_css = cset->subsys[memory_cgrp_id]; + blkcg_css = cset->subsys[io_cgrp_id]; + if (!memcg_css || !blkcg_css) + return; + if ((memcg_css == &root_mem_cgroup->css) || + (blkcg_css == blkcg_root_css)) + return; + if (mutex_trylock(&cgroup_mutex)) { + struct cgroup *blk_cgroup = blkcg_css->cgroup; + + if (IS_ERR(blk_cgroup)) { + mutex_unlock(&cgroup_mutex); + return; + } + wb_attach_memcg_to_blkcg(memcg_css, blkcg_css); + mutex_unlock(&cgroup_mutex); + } else { + struct cgroup *blk_cgroup = blkcg_css->cgroup; + + if (IS_ERR(blk_cgroup)) + return; + wb_attach_memcg_to_blkcg(memcg_css, blkcg_css); + } +} /* * cgwb_lock protects bdi->cgwb_tree, blkcg->cgwb_list, and memcg->cgwb_list.