diff options
author | openeuler-ci-bot <george@openeuler.sh> | 2024-04-22 01:43:51 +0000 |
---|---|---|
committer | Gitee <noreply@gitee.com> | 2024-04-22 01:43:51 +0000 |
commit | bccd28ea886e8aa7b6dbc1e13211b54ec87a5f58 (patch) | |
tree | 51411f4fac100bec19fc67ee6aacbb7b27acc03b | |
parent | 81b112bf9b90b5f19f10905296318b4ba61b7c69 (diff) | |
parent | 16e36ed6fba6041e8a249bae5dd1690da5d2e398 (diff) | |
download | openEuler-kernel-bccd28ea886e8aa7b6dbc1e13211b54ec87a5f58.tar.gz |
!6299 sp2 fix deadlock in cgroup1_writeback
Merge Pull Request from: @ci-robot
PR sync from: Chen Ridong <chenridong@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/H4KAPZ7W3PV2SLPEG46EARTNZU32S7MG/
*** BLURB HERE ***
Chen Ridong (1):
cgroup_writeback: fix softlockup for blkcg->memcg_list
Lu Jialin (1):
cgroup_writeback: fix deadlock in cgroup1_writeback
--
2.34.1
https://gitee.com/openeuler/kernel/issues/I8Y0RW
https://gitee.com/openeuler/kernel/issues/I99KM6
Link:https://gitee.com/openeuler/kernel/pulls/6299
Reviewed-by: Jialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com>
-rw-r--r-- | mm/backing-dev.c | 17 | ||||
-rw-r--r-- | mm/memcontrol.c | 22 |
2 files changed, 25 insertions, 14 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 45ac57fd6e7a3c..fa2e2682615030 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -438,8 +438,8 @@ static struct cgroup_subsys_state *cgwbv1_get_blkcss(struct mem_cgroup *memcg) struct cgroup_subsys_state *blkcg_css; rcu_read_lock(); - blkcg_css = memcg->wb_blk_css; - if (!css_tryget_online(blkcg_css)) { + blkcg_css = READ_ONCE(memcg->wb_blk_css); + if (!blkcg_css || !css_tryget_online(blkcg_css)) { blkcg_css = blkcg_root_css; css_get(blkcg_css); } @@ -1067,6 +1067,7 @@ EXPORT_SYMBOL(wait_iff_congested); #include "../kernel/cgroup/cgroup-internal.h" static bool cgroup1_writeback __read_mostly; +DEFINE_SPINLOCK(wb_blk_memlist_lock); bool cgroup1_writeback_enabled(void) { @@ -1080,6 +1081,7 @@ static void wb_kill_memcg(struct cgroup_subsys_state *memcg_css) list_del_init(&memcg->memcg_node); css_put(memcg->wb_blk_css); + memcg->wb_blk_css = NULL; } static void wb_kill_blkcg(struct cgroup_subsys_state *blkcg_css) @@ -1103,26 +1105,26 @@ void wb_kill_memcg_blkcg(struct cgroup_subsys_state *css) if (!cgroup1_writeback) return; - lockdep_assert_held(&cgroup_mutex); - + spin_lock(&wb_blk_memlist_lock); if (ss->id == io_cgrp_id) wb_kill_blkcg(css); else if (ss->id == memory_cgrp_id) wb_kill_memcg(css); + spin_unlock(&wb_blk_memlist_lock); } void wb_attach_memcg_to_blkcg(struct cgroup_subsys_state *memcg_css, struct cgroup_subsys_state *blkcg_css) { struct mem_cgroup *memcg = mem_cgroup_from_css(memcg_css); - struct cgroup_subsys_state *pre_blkcss = memcg->wb_blk_css; + struct cgroup_subsys_state *pre_blkcss = NULL; struct blkcg *blkcg = css_to_blkcg(blkcg_css); if (!cgroup1_writeback) return; - lockdep_assert_held(&cgroup_mutex); - + spin_lock(&wb_blk_memlist_lock); + pre_blkcss = memcg->wb_blk_css; css_get(blkcg_css); memcg->wb_blk_css = blkcg_css; if (pre_blkcss == NULL) @@ -1131,6 +1133,7 @@ void wb_attach_memcg_to_blkcg(struct cgroup_subsys_state *memcg_css, list_move(&memcg->memcg_node, &blkcg->memcg_list); css_put(pre_blkcss); } + spin_unlock(&wb_blk_memlist_lock); } static int __init enable_cgroup1_writeback(char *s) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 561d4a15779897..c4444f2a197be1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -5468,15 +5468,21 @@ static int wb_blkio_show(struct seq_file *m, void *v) if (!path) return -ENOMEM; - mutex_lock(&cgroup_mutex); - blkcg_css = memcg->wb_blk_css; + rcu_read_lock(); + blkcg_css = READ_ONCE(memcg->wb_blk_css); + if (!blkcg_css || !css_tryget_online(blkcg_css)) { + kfree(path); + rcu_read_unlock(); + return -EINVAL; + } blkcg_cgroup = blkcg_css->cgroup; blkcg_id = cgroup_ino(blkcg_cgroup); cgroup_path(blkcg_cgroup, path, PATH_MAX); - mutex_unlock(&cgroup_mutex); seq_printf(m, "wb_blkio_path:%s\n", path); seq_printf(m, "wb_blkio_ino:%lu\n", blkcg_id); kfree(path); + css_put(blkcg_css); + rcu_read_unlock(); return 0; } @@ -5499,22 +5505,24 @@ static ssize_t wb_blkio_write(struct kernfs_open_file *of, char *buf, if (ret) return ret; - mutex_lock(&cgroup_mutex); + rcu_read_lock(); root = blkcg_root_css->cgroup->root; blk_cgroup = cgroup1_get_from_id(root, cgrp_id); if (IS_ERR(blk_cgroup)) { - mutex_unlock(&cgroup_mutex); + rcu_read_unlock(); return -EINVAL; } blkcg_css = cgroup_tryget_css(blk_cgroup, &io_cgrp_subsys); - if (!blkcg_css) + if (!blkcg_css) { + ret = -EINVAL; goto out_unlock; + } wb_attach_memcg_to_blkcg(memcg_css, blkcg_css); css_put(blkcg_css); out_unlock: cgroup_put(blk_cgroup); - mutex_unlock(&cgroup_mutex); + rcu_read_unlock(); return ret < 0 ? ret : nbytes; } |