Unverified Commit d64b4f93 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3434 arm64/ascend: Add new enable_oom_killer interface for oom contrl

parents af30366f b498d9f1
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -112,4 +112,28 @@ extern void oom_killer_enable(void);

extern struct task_struct *find_lock_task_mm(struct task_struct *p);

#define OOM_TYPE_NOMEM		0
#define OOM_TYPE_OVERCOMMIT	1
#define OOM_TYPE_CGROUP		2

#ifdef CONFIG_ASCEND_OOM
int register_hisi_oom_notifier(struct notifier_block *nb);
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 */
+10 −0
Original line number Diff line number Diff line
@@ -1312,6 +1312,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 n
	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"

+20 −0
Original line number Diff line number Diff line
@@ -1967,6 +1967,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;
			oom_type_notifier_call(OOM_TYPE_CGROUP, NULL);
		}
		return false;
	}
@@ -2031,6 +2032,8 @@ bool mem_cgroup_oom_synchronize(bool handle)
	if (locked)
		mem_cgroup_oom_notify(memcg);

	oom_type_notifier_call(OOM_TYPE_CGROUP, NULL);

	schedule();
	mem_cgroup_unmark_under_oom(memcg);
	finish_wait(&memcg_oom_waitq, &owait.wait);
@@ -3199,6 +3202,20 @@ int __memcg_kmem_charge_page(struct page *page, gfp_t gfp, int order)
	return ret;
}

#ifdef CONFIG_ASCEND_OOM
void hisi_oom_recover(struct obj_cgroup *objcg)
{
	struct mem_cgroup *memcg;

	memcg = get_mem_cgroup_from_objcg(objcg);
	if (!mem_cgroup_is_root(memcg))
		memcg_oom_recover(memcg);
	css_put(&memcg->css);
}
#else
static inline void hisi_oom_recover(struct obj_cgroup *objcg) { }
#endif

/**
 * __memcg_kmem_uncharge_page: uncharge a kmem page
 * @page: page to uncharge
@@ -3215,6 +3232,9 @@ void __memcg_kmem_uncharge_page(struct page *page, int order)

	objcg = __folio_objcg(folio);
	obj_cgroup_uncharge_pages(objcg, nr_pages);

	hisi_oom_recover(objcg);

	folio->memcg_data = 0;
	obj_cgroup_put(objcg);
}
+57 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@
static int sysctl_panic_on_oom;
static int sysctl_oom_kill_allocating_task;
static int sysctl_oom_dump_tasks = 1;
static int sysctl_enable_oom_killer = 1;

/*
 * 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(OOM_TYPE_NOMEM, 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(OOM_TYPE_NOMEM, oc);
		return false;
	}

	if (!is_memcg_oom(oc)) {
		blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
		if (freed > 0 && !is_sysrq_oom(oc))
+2 −0
Original line number Diff line number Diff line
@@ -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;