mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
mm: oom_kill: Support further prioritization of OOM kills
When the OOM killer selects a task to kill it considers all tasks with an oom_score_adj value > OOM_SCORE_ADJ_MIN. This doesn't work well when the OS has 'high priority' tasks which should only be considered for killing after all other 'lower priority' tasks have first been killed. Add support for two new configs, PRIORITIZE_OOM_TASKS and OOM_TASK_PRIORITY_ADJ_LIMIT, which allows the system to be configured so that the OOM killer will first try to kill tasks which have an oom_score_adj greater than a certain value. Change-Id: Ic613138ae147427fd69b447ca5b674619ca625b2 Signed-off-by: Liam Mark <lmark@codeaurora.org>
This commit is contained in:
parent
333b4ccb21
commit
0c1d7417aa
3 changed files with 81 additions and 10 deletions
|
|
@ -49,6 +49,9 @@ struct oom_control {
|
|||
unsigned long totalpages;
|
||||
struct task_struct *chosen;
|
||||
unsigned long chosen_points;
|
||||
#ifdef CONFIG_PRIORITIZE_OOM_TASKS
|
||||
short min_kill_adj;
|
||||
#endif
|
||||
|
||||
/* Used to print the constraint info. */
|
||||
enum oom_constraint constraint;
|
||||
|
|
|
|||
27
mm/Kconfig
27
mm/Kconfig
|
|
@ -805,4 +805,31 @@ config ARCH_HAS_PTE_SPECIAL
|
|||
config ARCH_HAS_HUGEPD
|
||||
bool
|
||||
|
||||
config PRIORITIZE_OOM_TASKS
|
||||
bool "Attempt to further prioritize OOM killer kills"
|
||||
depends on QGKI
|
||||
help
|
||||
When the OOM killer selects a task to kill it considers all tasks
|
||||
with a oom_score_adj value > OOM_SCORE_ADJ_MIN. This doesn't work
|
||||
well when the OS has 'high priority' tasks which should only be
|
||||
considered for killing after all other 'lower priority' tasks
|
||||
have first been killed.
|
||||
|
||||
Enable this option to impose a limit on the minimum task
|
||||
oom_score_adj which should first be considered for killing
|
||||
before allowing the OOM killer to select tasks without
|
||||
limitation.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config OOM_TASK_PRIORITY_ADJ_LIMIT
|
||||
int "Min oom_score_adj when priotizing OOM killer kills"
|
||||
depends on PRIORITIZE_OOM_TASKS
|
||||
range -1000 1000
|
||||
default 0
|
||||
help
|
||||
With this parameter you can limit the OOM killer to first kill
|
||||
tasks with an oom_score_adj value above a certain threshold
|
||||
before considering tasks with a lower oom_score_adj value.
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -317,6 +317,10 @@ static int oom_evaluate_task(struct task_struct *task, void *arg)
|
|||
{
|
||||
struct oom_control *oc = arg;
|
||||
unsigned long points;
|
||||
#ifdef CONFIG_PRIORITIZE_OOM_TASKS
|
||||
struct task_struct *p;
|
||||
short adj;
|
||||
#endif
|
||||
|
||||
if (oom_unkillable_task(task))
|
||||
goto next;
|
||||
|
|
@ -337,6 +341,18 @@ static int oom_evaluate_task(struct task_struct *task, void *arg)
|
|||
goto abort;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PRIORITIZE_OOM_TASKS
|
||||
p = find_lock_task_mm(task);
|
||||
if (!p)
|
||||
goto next;
|
||||
|
||||
adj = p->signal->oom_score_adj;
|
||||
task_unlock(p);
|
||||
|
||||
if (adj < oc->min_kill_adj)
|
||||
goto next;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If task is allocating a lot of memory and has been marked to be
|
||||
* killed first if it triggers an oom, then select it.
|
||||
|
|
@ -994,7 +1010,11 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
|
|||
}
|
||||
task_unlock(victim);
|
||||
|
||||
if (__ratelimit(&oom_rs))
|
||||
if (__ratelimit(&oom_rs)
|
||||
#ifdef CONFIG_PRIORITIZE_OOM_TASKS
|
||||
&& oc->min_kill_adj < CONFIG_OOM_TASK_PRIORITY_ADJ_LIMIT
|
||||
#endif
|
||||
)
|
||||
dump_header(oc, victim);
|
||||
|
||||
/*
|
||||
|
|
@ -1070,13 +1090,9 @@ bool out_of_memory(struct oom_control *oc)
|
|||
|
||||
if (oom_killer_disabled)
|
||||
return false;
|
||||
|
||||
if (try_online_one_block(numa_node_id())) {
|
||||
/* Got some memory back */
|
||||
WARN(1, "OOM killer had to online a memory block\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PRIORITIZE_OOM_TASKS
|
||||
oc->min_kill_adj = OOM_SCORE_ADJ_MIN;
|
||||
#endif
|
||||
if (!is_memcg_oom(oc)) {
|
||||
blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
|
||||
if (freed > 0)
|
||||
|
|
@ -1112,19 +1128,44 @@ bool out_of_memory(struct oom_control *oc)
|
|||
oc->constraint = constrained_alloc(oc);
|
||||
if (oc->constraint != CONSTRAINT_MEMORY_POLICY)
|
||||
oc->nodemask = NULL;
|
||||
check_panic_on_oom(oc);
|
||||
|
||||
if (!is_memcg_oom(oc) && sysctl_oom_kill_allocating_task &&
|
||||
current->mm && !oom_unkillable_task(current) &&
|
||||
oom_cpuset_eligible(current, oc) &&
|
||||
current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
|
||||
check_panic_on_oom(oc);
|
||||
get_task_struct(current);
|
||||
oc->chosen = current;
|
||||
oom_kill_process(oc, "Out of memory (oom_kill_allocating_task)");
|
||||
return true;
|
||||
}
|
||||
|
||||
select_bad_process(oc);
|
||||
#ifdef CONFIG_PRIORITIZE_OOM_TASKS
|
||||
if (oc->min_kill_adj < CONFIG_OOM_TASK_PRIORITY_ADJ_LIMIT) {
|
||||
short prev_min_kill_adj = oc->min_kill_adj;
|
||||
|
||||
oc->min_kill_adj = CONFIG_OOM_TASK_PRIORITY_ADJ_LIMIT;
|
||||
select_bad_process(oc);
|
||||
if (!oc->chosen) {
|
||||
pr_warn_ratelimited("Could not find task with adj >= %d\n",
|
||||
CONFIG_OOM_TASK_PRIORITY_ADJ_LIMIT);
|
||||
oc->min_kill_adj = prev_min_kill_adj;
|
||||
oc->chosen_points = 0;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!oc->chosen) {
|
||||
if (try_online_one_block(numa_node_id())) {
|
||||
/* Got some memory back */
|
||||
WARN(1, "OOM killer had to online a memory block\n");
|
||||
return true;
|
||||
}
|
||||
check_panic_on_oom(oc);
|
||||
select_bad_process(oc);
|
||||
}
|
||||
|
||||
/* Found nothing?!?! */
|
||||
if (!oc->chosen) {
|
||||
dump_header(oc, NULL);
|
||||
|
|
|
|||
Loading…
Reference in a new issue