提交 fe76d537 编写于 作者: W Weilong Chen 提交者: Yang Yingliang

arm64/ascend: Add new enable_oom_killer interface for oom contrl

ascend inclusion
category: feature
bugzilla: NA
CVE: NA

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

Support disable oom-killer, and report oom events to bbox
vm.enable_oom_killer:
	0: disable oom killer
	1: enable oom killer (default,compatible with mainline)
	2: disable oom killer and panic on oom
Signed-off-by: NWeilong Chen <chenweilong@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 221302d3
...@@ -1335,6 +1335,17 @@ config ASCEND_DVPP_MMAP ...@@ -1335,6 +1335,17 @@ config ASCEND_DVPP_MMAP
special memory for DvPP processor, the new flag is only valid for Ascend special memory for DvPP processor, the new flag is only valid for Ascend
platform. platform.
config ASCEND_OOM
bool "Enable support for disable oom killer"
default y
help
In some cases we hopes that the oom will not kill the process when it occurs,
be able to notify the black box to report the event, and be able to trigger
the panic to locate the problem.
vm.enable_oom_killer:
0: disable oom killer
1: enable oom killer (default,compatible with mainline)
2: disable oom killer and panic on oom
endif endif
endmenu endmenu
......
...@@ -117,4 +117,15 @@ extern struct task_struct *find_lock_task_mm(struct task_struct *p); ...@@ -117,4 +117,15 @@ extern struct task_struct *find_lock_task_mm(struct task_struct *p);
extern int sysctl_oom_dump_tasks; extern int sysctl_oom_dump_tasks;
extern int sysctl_oom_kill_allocating_task; extern int sysctl_oom_kill_allocating_task;
extern int sysctl_panic_on_oom; extern int sysctl_panic_on_oom;
#ifdef CONFIG_ASCEND_OOM
#define HISI_OOM_TYPE_NOMEM 0
#define HISI_OOM_TYPE_OVERCOMMIT 1
#define HISI_OOM_TYPE_CGROUP 2
extern int sysctl_enable_oom_killer;
extern int register_hisi_oom_notifier(struct notifier_block *nb);
extern int hisi_oom_notifier_call(unsigned long val, void *v);
extern int unregister_hisi_oom_notifier(struct notifier_block *nb);
#endif
#endif /* _INCLUDE_LINUX_OOM_H */ #endif /* _INCLUDE_LINUX_OOM_H */
...@@ -1264,6 +1264,18 @@ static struct ctl_table vm_table[] = { ...@@ -1264,6 +1264,18 @@ static struct ctl_table vm_table[] = {
.extra1 = &zero, .extra1 = &zero,
.extra2 = &two, .extra2 = &two,
}, },
#ifdef CONFIG_ASCEND_OOM
{
/* 0: diasable, 1: enable, 2: disable and panic on oom */
.procname = "enable_oom_killer",
.data = &sysctl_enable_oom_killer,
.maxlen = sizeof(sysctl_enable_oom_killer),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &two,
},
#endif
{ {
.procname = "oom_kill_allocating_task", .procname = "oom_kill_allocating_task",
.data = &sysctl_oom_kill_allocating_task, .data = &sysctl_oom_kill_allocating_task,
......
...@@ -1729,6 +1729,9 @@ static enum oom_status mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int ...@@ -1729,6 +1729,9 @@ static enum oom_status mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int
current->memcg_in_oom = memcg; current->memcg_in_oom = memcg;
current->memcg_oom_gfp_mask = mask; current->memcg_oom_gfp_mask = mask;
current->memcg_oom_order = order; current->memcg_oom_order = order;
#ifdef CONFIG_ASCEND_OOM
hisi_oom_notifier_call(HISI_OOM_TYPE_CGROUP, NULL);
#endif
return OOM_ASYNC; return OOM_ASYNC;
} }
...@@ -1802,6 +1805,9 @@ bool mem_cgroup_oom_synchronize(bool handle) ...@@ -1802,6 +1805,9 @@ bool mem_cgroup_oom_synchronize(bool handle)
mem_cgroup_out_of_memory(memcg, current->memcg_oom_gfp_mask, mem_cgroup_out_of_memory(memcg, current->memcg_oom_gfp_mask,
current->memcg_oom_order); current->memcg_oom_order);
} else { } else {
#ifdef CONFIG_ASCEND_OOM
hisi_oom_notifier_call(HISI_OOM_TYPE_CGROUP, NULL);
#endif
schedule(); schedule();
mem_cgroup_unmark_under_oom(memcg); mem_cgroup_unmark_under_oom(memcg);
finish_wait(&memcg_oom_waitq, &owait.wait); finish_wait(&memcg_oom_waitq, &owait.wait);
......
...@@ -52,6 +52,9 @@ ...@@ -52,6 +52,9 @@
int sysctl_panic_on_oom; int sysctl_panic_on_oom;
int sysctl_oom_kill_allocating_task; int sysctl_oom_kill_allocating_task;
int sysctl_oom_dump_tasks = 1; int sysctl_oom_dump_tasks = 1;
#ifdef CONFIG_ASCEND_OOM
int sysctl_enable_oom_killer = 1;
#endif
/* /*
* Serializes oom killer invocations (out_of_memory()) from all contexts to * Serializes oom killer invocations (out_of_memory()) from all contexts to
...@@ -1047,6 +1050,42 @@ int unregister_oom_notifier(struct notifier_block *nb) ...@@ -1047,6 +1050,42 @@ int unregister_oom_notifier(struct notifier_block *nb)
} }
EXPORT_SYMBOL_GPL(unregister_oom_notifier); EXPORT_SYMBOL_GPL(unregister_oom_notifier);
#ifdef CONFIG_ASCEND_OOM
static BLOCKING_NOTIFIER_HEAD(hisi_oom_notify_list);
int register_hisi_oom_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&hisi_oom_notify_list, nb);
}
EXPORT_SYMBOL_GPL(register_hisi_oom_notifier);
static unsigned long last_jiffies;
int hisi_oom_notifier_call(unsigned long val, void *v)
{
/* when enable oom killer, just return */
if (sysctl_enable_oom_killer == 1)
return 0;
/* Print time interval to 10 seconds */
if (time_after(jiffies, last_jiffies + 10 * HZ)) {
pr_err("OOM_NOTIFIER: oom type %lu\n", val);
dump_stack();
show_mem(SHOW_MEM_FILTER_NODES, NULL);
dump_tasks(NULL, 0);
last_jiffies = jiffies;
}
return blocking_notifier_call_chain(&hisi_oom_notify_list, val, v);
}
EXPORT_SYMBOL_GPL(hisi_oom_notifier_call);
int unregister_hisi_oom_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&hisi_oom_notify_list, nb);
}
EXPORT_SYMBOL_GPL(unregister_hisi_oom_notifier);
#endif
/** /**
* out_of_memory - kill the "best" process when we run out of memory * out_of_memory - kill the "best" process when we run out of memory
* @oc: pointer to struct oom_control * @oc: pointer to struct oom_control
...@@ -1060,10 +1099,27 @@ bool out_of_memory(struct oom_control *oc) ...@@ -1060,10 +1099,27 @@ bool out_of_memory(struct oom_control *oc)
{ {
unsigned long freed = 0; unsigned long freed = 0;
enum oom_constraint constraint = CONSTRAINT_NONE; enum oom_constraint constraint = CONSTRAINT_NONE;
#ifdef CONFIG_ASCEND_OOM
unsigned long oom_type;
#endif
if (oom_killer_disabled) if (oom_killer_disabled)
return false; return false;
#ifdef CONFIG_ASCEND_OOM
if (sysctl_enable_oom_killer == 0 || sysctl_enable_oom_killer == 2) {
if (is_memcg_oom(oc))
oom_type = HISI_OOM_TYPE_CGROUP;
else
oom_type = HISI_OOM_TYPE_NOMEM;
hisi_oom_notifier_call(oom_type, NULL);
if (unlikely(sysctl_enable_oom_killer == 2))
panic("Out of memory, panic by sysctl_enable_oom_killer");
return false;
}
#endif
if (!is_memcg_oom(oc)) { if (!is_memcg_oom(oc)) {
blocking_notifier_call_chain(&oom_notify_list, 0, &freed); blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
if (freed > 0) if (freed > 0)
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#ifdef CONFIG_ASCEND_OOM
#include <linux/oom.h>
#endif
#include "internal.h" #include "internal.h"
...@@ -726,6 +729,9 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) ...@@ -726,6 +729,9 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
if (percpu_counter_read_positive(&vm_committed_as) < allowed) if (percpu_counter_read_positive(&vm_committed_as) < allowed)
return 0; return 0;
error: error:
#ifdef CONFIG_ASCEND_OOM
hisi_oom_notifier_call(HISI_OOM_TYPE_OVERCOMMIT, NULL);
#endif
vm_unacct_memory(pages); vm_unacct_memory(pages);
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册