From: Liu Shixin <liushixin2(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 175105
CVE: NA
-------------------------------------------------
When !CONFIG_SYSCTL, drop_caches_loop_limit is invisible.
Add cmdline "drop_caches_loop_limit=" to set it.
This parameter can limit the number of loops per node.
Fixes: 90394d30702e ("mm/vmscan: add drop_caches_loop_limit to break loop in drop_slab_node")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
---
fs/drop_caches.c | 1 -
include/linux/mm.h | 2 +-
kernel/sysctl.c | 2 +-
mm/vmscan.c | 19 +++++++++++++------
4 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index 1f866b32cd150..dc1a1d5d825b4 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -13,7 +13,6 @@
/* A global variable is a bit ugly, but it keeps the code simple */
int sysctl_drop_caches;
-unsigned int sysctl_drop_caches_loop_limit __read_mostly;
static void drop_pagecache_sb(struct super_block *sb, void *unused)
{
diff --git a/include/linux/mm.h b/include/linux/mm.h
index db53f49e13b91..d3d62cd3ee07c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2769,7 +2769,7 @@ extern bool process_shares_mm(struct task_struct *p, struct mm_struct *mm);
#ifdef CONFIG_SYSCTL
extern int sysctl_drop_caches;
-extern unsigned int sysctl_drop_caches_loop_limit;
+extern unsigned int drop_caches_loop_limit;
int drop_caches_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
#endif
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 1733b8c71b117..91d4fe5b2770f 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1479,7 +1479,7 @@ static struct ctl_table vm_table[] = {
},
{
.procname = "drop_caches_loop_limit",
- .data = &sysctl_drop_caches_loop_limit,
+ .data = &drop_caches_loop_limit,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_douintvec,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3d7716e2e2c66..b5f5a366d155f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -723,12 +723,21 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
return freed;
}
+unsigned int drop_caches_loop_limit __read_mostly;
+static int __init drop_caches_loop_limit_setup(char *s)
+{
+ int ret = kstrtouint(s, 10, &drop_caches_loop_limit);
+
+ if (ret)
+ pr_info("Parse drop_caches_loop_limit failed: ret: %d\n", ret);
+ return 1;
+}
+__setup("drop_caches_loop_limit=", drop_caches_loop_limit_setup);
+
void drop_slab_node(int nid)
{
unsigned long freed;
-#ifdef CONFIG_SYSCTL
unsigned int counts = 0;
-#endif
do {
struct mem_cgroup *memcg = NULL;
@@ -742,17 +751,15 @@ void drop_slab_node(int nid)
freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
-#ifdef CONFIG_SYSCTL
- if (unlikely(sysctl_drop_caches_loop_limit)) {
+ if (unlikely(drop_caches_loop_limit)) {
counts++;
- if (counts >= sysctl_drop_caches_loop_limit) {
+ if (counts >= drop_caches_loop_limit) {
pr_info("%s (%d): drop_caches early break: %u loops\n",
current->comm, task_pid_nr(current),
counts);
return;
}
}
-#endif
} while (freed > 10);
}
--
2.25.1