On 2023/12/11 17:12, Yuan Can wrote:
From: Weilong Chen chenweilong@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8NC0E 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)
Signed-off-by: Weilong Chen chenweilong@huawei.com
include/linux/oom.h | 26 +++++++++++++++++++++ mm/Kconfig | 10 ++++++++ mm/memcontrol.c | 4 ++++ mm/oom_kill.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ mm/util.c | 2 ++ 5 files changed, 99 insertions(+)
diff --git a/include/linux/oom.h b/include/linux/oom.h index 7d0c9c48a0c5..f88f34d2b4dd 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -112,4 +112,30 @@ extern void oom_killer_enable(void);
extern struct task_struct *find_lock_task_mm(struct task_struct *p);
+extern int sysctl_enable_oom_killer;
+#define OOM_TYPE_NOMEM 0 +#define OOM_TYPE_OVERCOMMIT 1 +#define OOM_TYPE_CGROUP 2
这些type应该没有外部使用者,放到宏控里面
+#ifdef CONFIG_ASCEND_OOM +extern int register_hisi_oom_notifier(struct notifier_block *nb); +extern int unregister_hisi_oom_notifier(struct notifier_block *nb); +int oom_type_notifier_call(unsigned int type, struct oom_control *oc); +#else +static inline int register_hisi_oom_notifier(struct notifier_block *nb) +{
- return -EINVAL;
+}
+static inline int unregister_hisi_oom_notifier(struct notifier_block *nb) +{
- return -EINVAL;
+}
+static inline int oom_type_notifier_call(unsigned int type, struct oom_control *oc) +{
- return -EINVAL;
+} +#endif #endif /* _INCLUDE_LINUX_OOM_H */ diff --git a/mm/Kconfig b/mm/Kconfig index 0f68e5bbeb89..cdef59dc373c 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1302,6 +1302,16 @@ config SHARE_POOL in kernel and user level, which is only enabled for ascend platform. To enable this feature, enable_ascend_share_pool bootarg is needed.
+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)
source "mm/damon/Kconfig"
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 8a881ab21f6c..08af3c8df6f3 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1955,6 +1955,7 @@ static bool mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int order) current->memcg_in_oom = memcg; current->memcg_oom_gfp_mask = mask; current->memcg_oom_order = order;
} return false; }oom_type_notifier_call(OOM_TYPE_CGROUP, NULL);
@@ -2019,6 +2020,9 @@ bool mem_cgroup_oom_synchronize(bool handle) if (locked) mem_cgroup_oom_notify(memcg);
- if (!sysctl_enable_oom_killer)
oom_type_notifier_call(OOM_TYPE_CGROUP, NULL);
函数里面已经判断了,不需要在次判断;sysctl_enable_oom_killer
schedule(); mem_cgroup_unmark_under_oom(memcg); finish_wait(&memcg_oom_waitq, &owait.wait); diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 44bde56ecd02..fb9dc88ff17b 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -55,6 +55,7 @@ static int sysctl_panic_on_oom; static int sysctl_oom_kill_allocating_task; static int sysctl_oom_dump_tasks = 1; +int sysctl_enable_oom_killer = 1;
上面改好了感觉可以搞成static了
/*
- Serializes oom killer invocations (out_of_memory()) from all contexts to
@@ -724,6 +725,17 @@ static struct ctl_table vm_oom_kill_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, +#ifdef CONFIG_ASCEND_OOM
- {
.procname = "enable_oom_killer",
.data = &sysctl_enable_oom_killer,
.maxlen = sizeof(sysctl_enable_oom_killer),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
- },
+#endif {} }; #endif @@ -1073,6 +1085,7 @@ static void check_panic_on_oom(struct oom_control *oc) if (is_sysrq_oom(oc)) return; dump_header(oc, NULL);
- oom_type_notifier_call(0, oc); panic("Out of memory: %s panic_on_oom is enabled\n", sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); }
@@ -1091,6 +1104,45 @@ int unregister_oom_notifier(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(unregister_oom_notifier);
+#ifdef CONFIG_ASCEND_OOM +static BLOCKING_NOTIFIER_HEAD(oom_type_notify_list);
+int register_hisi_oom_notifier(struct notifier_block *nb) +{
- return blocking_notifier_chain_register(&oom_type_notify_list, nb);
+} +EXPORT_SYMBOL_GPL(register_hisi_oom_notifier);
+int unregister_hisi_oom_notifier(struct notifier_block *nb) +{
- return blocking_notifier_chain_unregister(&oom_type_notify_list, nb);
+} +EXPORT_SYMBOL_GPL(unregister_hisi_oom_notifier);
+int oom_type_notifier_call(unsigned int type, struct oom_control *oc) +{
- struct oom_control oc_tmp = { 0 };
- static unsigned long caller_jiffies;
- if (sysctl_enable_oom_killer)
return -EINVAL;
- if (oc)
type = is_memcg_oom(oc) ? OOM_TYPE_CGROUP : OOM_TYPE_NOMEM;
- else
oc = &oc_tmp;
- if (printk_timed_ratelimit(&caller_jiffies, 10000)) {
pr_err("OOM_NOTIFIER: oom type %u\n", type);
dump_stack();
show_mem();
dump_tasks(oc);
- }
- return blocking_notifier_call_chain(&oom_type_notify_list, type, NULL);
+} +#endif
- /**
- out_of_memory - kill the "best" process when we run out of memory
- @oc: pointer to struct oom_control
@@ -1107,6 +1159,11 @@ bool out_of_memory(struct oom_control *oc) if (oom_killer_disabled) return false;
- if (!sysctl_enable_oom_killer) {
oom_type_notifier_call(0, oc);
return false;
- }
- if (!is_memcg_oom(oc)) { blocking_notifier_call_chain(&oom_notify_list, 0, &freed); if (freed > 0 && !is_sysrq_oom(oc))
diff --git a/mm/util.c b/mm/util.c index 90250cbc82fe..e41ac8a58eb5 100644 --- a/mm/util.c +++ b/mm/util.c @@ -26,6 +26,7 @@ #include <linux/share_pool.h>
#include <linux/uaccess.h> +#include <linux/oom.h>
#include "internal.h" #include "swap.h" @@ -981,6 +982,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) error: pr_warn_ratelimited("%s: pid: %d, comm: %s, not enough memory for the allocation\n", __func__, current->pid, current->comm);
oom_type_notifier_call(OOM_TYPE_OVERCOMMIT, NULL); vm_unacct_memory(pages);
return -ENOMEM;