提交 ceb5620e 编写于 作者: L Liu Shixin 提交者: Yang Yingliang

mm/vmscan: add drop_caches_loop_limit to break loop in drop_slab_node

hulk inclusion
category: bugfix
bugzilla: 175105
CVE: NA

-------------------------------------------------

Command 'echo 2 > /proc/sys/vm/drop_caches' could lead to a loop in
drop_slab_node for a long while. Add /proc/sys/vm/drop_caches_loop_limit
to break loop in drop_slab_node.
Signed-off-by: NLiu Shixin <liushixin2@huawei.com>
Reviewed-by: Ntong tiangen <tongtiangen@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 77b99b08
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
/* A global variable is a bit ugly, but it keeps the code simple */ /* A global variable is a bit ugly, but it keeps the code simple */
int sysctl_drop_caches; int sysctl_drop_caches;
unsigned int sysctl_drop_caches_loop_limit __read_mostly;
static void drop_pagecache_sb(struct super_block *sb, void *unused) static void drop_pagecache_sb(struct super_block *sb, void *unused)
{ {
......
...@@ -2766,6 +2766,7 @@ extern bool process_shares_mm(struct task_struct *p, struct mm_struct *mm); ...@@ -2766,6 +2766,7 @@ extern bool process_shares_mm(struct task_struct *p, struct mm_struct *mm);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
extern int sysctl_drop_caches; extern int sysctl_drop_caches;
extern unsigned int sysctl_drop_caches_loop_limit;
int drop_caches_sysctl_handler(struct ctl_table *, int, int drop_caches_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *); void __user *, size_t *, loff_t *);
#endif #endif
......
...@@ -1477,6 +1477,14 @@ static struct ctl_table vm_table[] = { ...@@ -1477,6 +1477,14 @@ static struct ctl_table vm_table[] = {
.extra1 = &one, .extra1 = &one,
.extra2 = &four, .extra2 = &four,
}, },
{
.procname = "drop_caches_loop_limit",
.data = &sysctl_drop_caches_loop_limit,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_douintvec,
},
#ifdef CONFIG_COMPACTION #ifdef CONFIG_COMPACTION
{ {
.procname = "compact_memory", .procname = "compact_memory",
......
...@@ -735,6 +735,9 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, ...@@ -735,6 +735,9 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid,
void drop_slab_node(int nid) void drop_slab_node(int nid)
{ {
unsigned long freed; unsigned long freed;
#ifdef CONFIG_SYSCTL
unsigned int counts = 0;
#endif
do { do {
struct mem_cgroup *memcg = NULL; struct mem_cgroup *memcg = NULL;
...@@ -747,6 +750,18 @@ void drop_slab_node(int nid) ...@@ -747,6 +750,18 @@ void drop_slab_node(int nid)
do { do {
freed += shrink_slab(GFP_KERNEL, nid, memcg, 0); freed += shrink_slab(GFP_KERNEL, nid, memcg, 0);
} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL); } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL);
#ifdef CONFIG_SYSCTL
if (unlikely(sysctl_drop_caches_loop_limit)) {
counts++;
if (counts >= sysctl_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); } while (freed > 10);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册