From fa523f8bb46f74b527137535ed9ae02e018ff430 Mon Sep 17 00:00:00 2001 From: CY Fan Date: Tue, 8 Mar 2022 20:40:07 +0800 Subject: [PATCH] memcg: fix memcg use case timeout issue ohos inclusion category: bugfix issue: #I4UC37 CVE: NA ----------------- This patch replaces the score_list_lock with the rwlock and skips the non-target memcg Signed-off-by: CY Fan --- include/linux/memcg_policy.h | 2 +- mm/memcg_control.c | 14 +++++++------- mm/memcg_reclaim.c | 25 ++++++++++++++++++++++--- mm/memcontrol.c | 4 ++-- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/include/linux/memcg_policy.h b/include/linux/memcg_policy.h index 201b0e973e3c..4aec2a1bb3ec 100644 --- a/include/linux/memcg_policy.h +++ b/include/linux/memcg_policy.h @@ -15,7 +15,7 @@ struct scan_control; extern struct list_head score_head; extern bool score_head_inited; -extern spinlock_t score_list_lock; +extern rwlock_t score_list_lock; extern struct cgroup_subsys memory_cgrp_subsys; #ifdef CONFIG_HYPERHOLD_FILE_LRU void shrink_anon_memcg(struct pglist_data *pgdat, diff --git a/mm/memcg_control.c b/mm/memcg_control.c index 985fcaa66943..dd62304a9c68 100644 --- a/mm/memcg_control.c +++ b/mm/memcg_control.c @@ -17,7 +17,7 @@ struct list_head score_head; bool score_head_inited; -DEFINE_SPINLOCK(score_list_lock); +DEFINE_RWLOCK(score_list_lock); DEFINE_MUTEX(reclaim_para_lock); /** @@ -40,7 +40,7 @@ struct mem_cgroup *get_next_memcg(struct mem_cgroup *prev) if (unlikely(!score_head_inited)) return NULL; - spin_lock_irqsave(&score_list_lock, flags); + read_lock_irqsave(&score_list_lock, flags); if (unlikely(!prev)) pos = &score_head; @@ -60,7 +60,7 @@ struct mem_cgroup *get_next_memcg(struct mem_cgroup *prev) memcg = NULL; unlock: - spin_unlock_irqrestore(&score_list_lock, flags); + read_unlock_irqrestore(&score_list_lock, flags); if (prev) css_put(&prev->css); @@ -83,7 +83,7 @@ struct mem_cgroup *get_prev_memcg(struct mem_cgroup *next) if (unlikely(!score_head_inited)) return NULL; - spin_lock_irqsave(&score_list_lock, flags); + read_lock_irqsave(&score_list_lock, flags); if (unlikely(!next)) pos = &score_head; @@ -106,7 +106,7 @@ struct mem_cgroup *get_prev_memcg(struct mem_cgroup *next) memcg = NULL; unlock: - spin_unlock_irqrestore(&score_list_lock, flags); + read_unlock_irqrestore(&score_list_lock, flags); if (next) css_put(&next->css); @@ -125,7 +125,7 @@ void memcg_app_score_update(struct mem_cgroup *target) struct list_head *tmp; unsigned long flags; - spin_lock_irqsave(&score_list_lock, flags); + write_lock_irqsave(&score_list_lock, flags); list_for_each_prev_safe(pos, tmp, &score_head) { struct mem_cgroup *memcg = list_entry(pos, struct mem_cgroup, score_node); @@ -134,7 +134,7 @@ void memcg_app_score_update(struct mem_cgroup *target) break; } list_move_tail(&target->score_node, pos); - spin_unlock_irqrestore(&score_list_lock, flags); + write_unlock_irqrestore(&score_list_lock, flags); } static u64 mem_cgroup_app_score_read(struct cgroup_subsys_state *css, diff --git a/mm/memcg_reclaim.c b/mm/memcg_reclaim.c index f88826c13ae2..74c3d4dfa08b 100644 --- a/mm/memcg_reclaim.c +++ b/mm/memcg_reclaim.c @@ -215,6 +215,18 @@ void shrink_anon_memcg(struct pglist_data *pgdat, sc->nr_reclaimed_anon += nr_reclaimed; } +static inline bool memcg_is_child_of(struct mem_cgroup *mcg, struct mem_cgroup *tmcg) +{ + while (!mem_cgroup_is_root(mcg)) { + if (mcg == tmcg) + break; + + mcg = parent_mem_cgroup(mcg); + } + + return (mcg == tmcg); +} + static void shrink_anon(struct pglist_data *pgdat, struct scan_control *sc, unsigned long *nr) { @@ -229,7 +241,12 @@ static void shrink_anon(struct pglist_data *pgdat, node_lruvec(pgdat), LRU_INACTIVE_ANON, MAX_NR_ZONES); while ((memcg = get_next_memcg(memcg))) { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); + struct lruvec *lruvec = NULL; + + if (!memcg_is_child_of(memcg, target_memcg)) + continue; + + lruvec = mem_cgroup_lruvec(memcg, pgdat); reclaimed = sc->nr_reclaimed; scanned = sc->nr_scanned; @@ -438,8 +455,10 @@ bool shrink_node_hyperhold(struct pglist_data *pgdat, struct scan_control *sc) get_scan_count_hyperhold(pgdat, sc, nr, &node_lru_pages); - /* Shrink the Total-File-LRU */ - shrink_file(pgdat, sc, nr); + if (!cgroup_reclaim(sc)) { + /* Shrink the Total-File-LRU */ + shrink_file(pgdat, sc, nr); + } /* Shrink Anon by iterating score_list */ shrink_anon(pgdat, sc, nr); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 30e068e95e21..b1d67bcfb617 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -5496,9 +5496,9 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css) #ifdef CONFIG_HYPERHOLD_MEMCG unsigned long flags; - spin_lock_irqsave(&score_list_lock, flags); + write_lock_irqsave(&score_list_lock, flags); list_del_init(&memcg->score_node); - spin_unlock_irqrestore(&score_list_lock, flags); + write_unlock_irqrestore(&score_list_lock, flags); css_put(css); #endif -- Gitee