From: Lu Jialin lujialin4@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4IMAK?from=project-issue CVE: NA
--------
This patch adds a default-false static key to disable memcg kswapd feature. User can enable by set memcg_kswapd in cmdline.
Signed-off-by: Lu Jialin lujialin4@huawei.com Reviewed-by: weiyang wang wangweiyang2@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/linux/memcontrol.h | 3 +++ mm/memcontrol.c | 43 ++++++++++++++++++++++++++++++-------- mm/vmscan.c | 3 ++- 3 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 46062d99f14d..e5826f1ff337 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -1863,6 +1863,9 @@ static inline void mem_cgroup_flush_foreign(struct bdi_writeback *wb)
#endif /* CONFIG_CGROUP_WRITEBACK */
+extern struct static_key_false memcg_kswapd_key; +#define mem_cgroup_kswapd_enabled static_branch_unlikely(&memcg_kswapd_key) + struct sock; bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index a3cf9c074cfa..8acf7ff56294 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -96,6 +96,10 @@ bool cgroup_memory_noswap __read_mostly; static DECLARE_WAIT_QUEUE_HEAD(memcg_cgwb_frn_waitq); #endif
+static bool cgroup_memory_kswapd = false; +DEFINE_STATIC_KEY_FALSE(memcg_kswapd_key); +EXPORT_SYMBOL(memcg_kswapd_key); + /* Whether legacy memory+swap accounting is active */ static bool do_memsw_account(void) { @@ -2364,10 +2368,15 @@ static void high_work_func(struct work_struct *work) { struct mem_cgroup *memcg;
- current->flags |= PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD; - memcg = container_of(work, struct mem_cgroup, high_work); - reclaim_high(memcg, MEMCG_CHARGE_BATCH, GFP_KERNEL); - current->flags &= ~(PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD); + if (mem_cgroup_kswapd_enabled) { + current->flags |= PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD; + memcg = container_of(work, struct mem_cgroup, high_work); + reclaim_high(memcg, MEMCG_CHARGE_BATCH, GFP_KERNEL); + current->flags &= ~(PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD); + } else { + memcg = container_of(work, struct mem_cgroup, high_work); + reclaim_high(memcg, MEMCG_CHARGE_BATCH, GFP_KERNEL); + } }
/* @@ -2537,11 +2546,17 @@ void mem_cgroup_handle_over_high(void) * memory.high is currently batched, whereas memory.max and the page * allocator run every time an allocation is made. */ - current->flags |= PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD; - nr_reclaimed = reclaim_high(memcg, - in_retry ? SWAP_CLUSTER_MAX : nr_pages, - GFP_KERNEL); - current->flags &= ~(PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD); + if (mem_cgroup_kswapd_enabled) { + current->flags |= PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD; + nr_reclaimed = reclaim_high(memcg, + in_retry ? SWAP_CLUSTER_MAX : nr_pages, + GFP_KERNEL); + current->flags &= ~(PF_SWAPWRITE | PF_MEMALLOC | PF_KSWAPD); + } else { + nr_reclaimed = reclaim_high(memcg, + in_retry ? SWAP_CLUSTER_MAX : nr_pages, + GFP_KERNEL); + }
/* * memory.high is breached and reclaim is unable to keep up. Throttle @@ -5477,6 +5492,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) struct mem_cgroup *memcg, *old_memcg; long error = -ENOMEM;
+ if (cgroup_memory_kswapd) + static_branch_enable(&memcg_kswapd_key); + old_memcg = set_active_memcg(parent); memcg = mem_cgroup_alloc(); set_active_memcg(old_memcg); @@ -7280,6 +7298,13 @@ static int __init cgroup_memory(char *s) } __setup("cgroup.memory=", cgroup_memory);
+static int __init memcg_kswapd(char *s) +{ + cgroup_memory_kswapd = true; + return 0; +} +__setup("memcg_kswapd", memcg_kswapd); + /* * subsys_initcall() for memory controller. * diff --git a/mm/vmscan.c b/mm/vmscan.c index 7fec6cf7a0ae..5b5cc00b195b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2843,8 +2843,9 @@ static bool is_memcg_kswapd_stopped(struct scan_control *sc) bool is_stop = false; unsigned long stop_flag = 0;
- if (!cgroup_reclaim(sc)) + if (!cgroup_reclaim(sc) || !mem_cgroup_kswapd_enabled) return false; + if (memcg->memory.max == PAGE_COUNTER_MAX) stop_flag = memcg->memory.high / 6; else