From 0a03d5467e3fa4a5e79e2d10a1400e425068e618 Mon Sep 17 00:00:00 2001 From: Jing Xiangfeng Date: Fri, 30 Apr 2021 19:16:48 +0800 Subject: [PATCH] memcg: fix kabi broken when enable CONFIG_MEMCG_QOS hulk inclusion category: feature bugzilla: 51827 CVE: NA -------------------------------------- Fix it by moving memcg_priority from struct mem_cgroup to struct mem_cgroup_extension. Signed-off-by: Jing Xiangfeng Reviewed-by: Kefeng Wang Signed-off-by: Yang Yingliang --- include/linux/memcontrol.h | 10 ++++++---- mm/memcontrol.c | 33 +++++++++++++++++++++++++-------- mm/oom_kill.c | 8 ++++++-- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 816fd5265ad0..cc2aafe7b746 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -287,10 +287,6 @@ struct mem_cgroup { bool tcpmem_active; int tcpmem_pressure; -#ifdef CONFIG_MEMCG_QOS - /* Currently support 0 and -1, in the future it can expand to other value */ - int memcg_priority; -#endif #ifdef CONFIG_MEMCG_KMEM /* Index in the kmem_cache->memcg_params.memcg_caches array */ int kmemcg_id; @@ -323,8 +319,14 @@ struct mem_cgroup_extension { struct list_head split_queue; unsigned long split_queue_len; struct mem_cgroup memcg; +#ifdef CONFIG_MEMCG_QOS + /* Currently support 0 and -1, in the future it can expand to other value */ + int memcg_priority; +#endif }; +#define to_memcg_ext(cgroup) container_of(cgroup, struct mem_cgroup_extension, memcg) + #ifdef CONFIG_MEMCG_QOS bool memcg_low_priority_scan_tasks(int (*)(struct task_struct *, void *), void *); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index acceb60758f3..0edc615f1d26 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3407,29 +3407,42 @@ static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css, static void memcg_qos_init(struct mem_cgroup *memcg) { struct mem_cgroup *parent = parent_mem_cgroup(memcg); + struct mem_cgroup_extension *memcg_ext; + struct mem_cgroup_extension *parent_ext; if (!parent) return; - if (parent->memcg_priority && parent->use_hierarchy) - memcg->memcg_priority = parent->memcg_priority; + memcg_ext = to_memcg_ext(memcg); + parent_ext = to_memcg_ext(parent); + + if (parent_ext->memcg_priority && parent->use_hierarchy) + memcg_ext->memcg_priority = parent_ext->memcg_priority; } static s64 memcg_qos_read(struct cgroup_subsys_state *css, struct cftype *cft) { - return mem_cgroup_from_css(css)->memcg_priority; + struct mem_cgroup *memcg = mem_cgroup_from_css(css); + struct mem_cgroup_extension *memcg_ext; + + memcg_ext = to_memcg_ext(memcg); + + return memcg_ext->memcg_priority; } static int memcg_qos_write(struct cgroup_subsys_state *css, struct cftype *cft, s64 val) { struct mem_cgroup *memcg = mem_cgroup_from_css(css); + struct mem_cgroup_extension *memcg_ext; + + memcg_ext = to_memcg_ext(memcg); if (val >= 0) { - memcg->memcg_priority = 0; + memcg_ext->memcg_priority = 0; } else { - memcg->memcg_priority = -1; + memcg_ext->memcg_priority = -1; } return 0; @@ -3439,13 +3452,15 @@ static struct mem_cgroup *memcg_find_max_usage(struct mem_cgroup *last) { struct mem_cgroup *iter, *max_memcg = NULL; struct cgroup_subsys_state *css; + struct mem_cgroup_extension *memcg_ext; unsigned long usage, max_usage = 0; rcu_read_lock(); css_for_each_descendant_pre(css, &root_mem_cgroup->css) { iter = mem_cgroup_from_css(css); + memcg_ext = to_memcg_ext(iter); - if (!iter->memcg_priority || iter == root_mem_cgroup || iter == last) + if (!memcg_ext->memcg_priority || iter == root_mem_cgroup || iter == last) continue; usage = mem_cgroup_usage(iter, false); @@ -3504,11 +3519,13 @@ bool memcg_low_priority_scan_tasks(int (*fn)(struct task_struct *, void *), void memcg_print_bad_task(void *arg, int ret) { struct oom_control *oc = arg; + struct mem_cgroup *memcg; + struct mem_cgroup_extension *memcg_ext; if (!ret && oc->chosen) { - struct mem_cgroup *memcg; memcg = mem_cgroup_from_task(oc->chosen); - if (memcg->memcg_priority) + memcg_ext = to_memcg_ext(memcg); + if (memcg_ext->memcg_priority) pr_info("The bad task [%d:%s] is from low-priority memcg.\n", oc->chosen->pid, oc->chosen->comm); } diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 8f68d1e6be22..19853b37a510 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -327,6 +327,8 @@ static bool oom_next_task(struct task_struct *task, struct oom_control *oc, { struct mem_cgroup *cur_memcg; struct mem_cgroup *oc_memcg; + struct mem_cgroup_extension *cur_ext; + struct mem_cgroup_extension *oc_ext; if (!points) @@ -337,14 +339,16 @@ static bool oom_next_task(struct task_struct *task, struct oom_control *oc, oc_memcg = mem_cgroup_from_task(oc->chosen); cur_memcg = mem_cgroup_from_task(task); + oc_ext = to_memcg_ext(oc_memcg); + cur_ext = to_memcg_ext(cur_memcg); - if (cur_memcg->memcg_priority == oc_memcg->memcg_priority) { + if (cur_ext->memcg_priority == oc_ext->memcg_priority) { if (points < oc->chosen_points) return true; return false; } /* if oc is low-priority, so skip the task */ - if (oc_memcg->memcg_priority) + if (oc_ext->memcg_priority) return true; return false; -- GitLab