aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoropeneuler-ci-bot <george@openeuler.sh>2024-04-22 01:43:51 +0000
committerGitee <noreply@gitee.com>2024-04-22 01:43:51 +0000
commitbccd28ea886e8aa7b6dbc1e13211b54ec87a5f58 (patch)
tree51411f4fac100bec19fc67ee6aacbb7b27acc03b
parent81b112bf9b90b5f19f10905296318b4ba61b7c69 (diff)
parent16e36ed6fba6041e8a249bae5dd1690da5d2e398 (diff)
downloadopenEuler-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.c17
-rw-r--r--mm/memcontrol.c22
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;
}