mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 14:41:27 +00:00
mm: oom: add memcg to oom_control
It's a part of oom context just like allocation order and nodemask, so let's move it to oom_control instead of passing it in the argument list. Link: http://lkml.kernel.org/r/40e03fd7aaf1f55c75d787128d6d17c5a71226c2.1464358556.git.vdavydov@virtuozzo.com Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com> Acked-by: Michal Hocko <mhocko@suse.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
798fd75695
commit
2a966b77ae
5 changed files with 25 additions and 22 deletions
|
@ -363,6 +363,7 @@ static void moom_callback(struct work_struct *ignored)
|
||||||
struct oom_control oc = {
|
struct oom_control oc = {
|
||||||
.zonelist = node_zonelist(first_memory_node, gfp_mask),
|
.zonelist = node_zonelist(first_memory_node, gfp_mask),
|
||||||
.nodemask = NULL,
|
.nodemask = NULL,
|
||||||
|
.memcg = NULL,
|
||||||
.gfp_mask = gfp_mask,
|
.gfp_mask = gfp_mask,
|
||||||
.order = -1,
|
.order = -1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,9 @@ struct oom_control {
|
||||||
/* Used to determine mempolicy */
|
/* Used to determine mempolicy */
|
||||||
nodemask_t *nodemask;
|
nodemask_t *nodemask;
|
||||||
|
|
||||||
|
/* Memory cgroup in which oom is invoked, or NULL for global oom */
|
||||||
|
struct mem_cgroup *memcg;
|
||||||
|
|
||||||
/* Used to determine cpuset and node locality requirement */
|
/* Used to determine cpuset and node locality requirement */
|
||||||
const gfp_t gfp_mask;
|
const gfp_t gfp_mask;
|
||||||
|
|
||||||
|
@ -83,11 +86,10 @@ extern unsigned long oom_badness(struct task_struct *p,
|
||||||
|
|
||||||
extern void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
extern void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
unsigned int points, unsigned long totalpages,
|
unsigned int points, unsigned long totalpages,
|
||||||
struct mem_cgroup *memcg, const char *message);
|
const char *message);
|
||||||
|
|
||||||
extern void check_panic_on_oom(struct oom_control *oc,
|
extern void check_panic_on_oom(struct oom_control *oc,
|
||||||
enum oom_constraint constraint,
|
enum oom_constraint constraint);
|
||||||
struct mem_cgroup *memcg);
|
|
||||||
|
|
||||||
extern enum oom_scan_t oom_scan_process_thread(struct oom_control *oc,
|
extern enum oom_scan_t oom_scan_process_thread(struct oom_control *oc,
|
||||||
struct task_struct *task, unsigned long totalpages);
|
struct task_struct *task, unsigned long totalpages);
|
||||||
|
|
|
@ -1259,6 +1259,7 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
|
||||||
struct oom_control oc = {
|
struct oom_control oc = {
|
||||||
.zonelist = NULL,
|
.zonelist = NULL,
|
||||||
.nodemask = NULL,
|
.nodemask = NULL,
|
||||||
|
.memcg = memcg,
|
||||||
.gfp_mask = gfp_mask,
|
.gfp_mask = gfp_mask,
|
||||||
.order = order,
|
.order = order,
|
||||||
};
|
};
|
||||||
|
@ -1281,7 +1282,7 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_panic_on_oom(&oc, CONSTRAINT_MEMCG, memcg);
|
check_panic_on_oom(&oc, CONSTRAINT_MEMCG);
|
||||||
totalpages = mem_cgroup_get_limit(memcg) ? : 1;
|
totalpages = mem_cgroup_get_limit(memcg) ? : 1;
|
||||||
for_each_mem_cgroup_tree(iter, memcg) {
|
for_each_mem_cgroup_tree(iter, memcg) {
|
||||||
struct css_task_iter it;
|
struct css_task_iter it;
|
||||||
|
@ -1329,7 +1330,7 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
|
||||||
|
|
||||||
if (chosen) {
|
if (chosen) {
|
||||||
points = chosen_points * 1000 / totalpages;
|
points = chosen_points * 1000 / totalpages;
|
||||||
oom_kill_process(&oc, chosen, points, totalpages, memcg,
|
oom_kill_process(&oc, chosen, points, totalpages,
|
||||||
"Memory cgroup out of memory");
|
"Memory cgroup out of memory");
|
||||||
}
|
}
|
||||||
unlock:
|
unlock:
|
||||||
|
|
|
@ -383,8 +383,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_header(struct oom_control *oc, struct task_struct *p,
|
static void dump_header(struct oom_control *oc, struct task_struct *p)
|
||||||
struct mem_cgroup *memcg)
|
|
||||||
{
|
{
|
||||||
pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n",
|
pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n",
|
||||||
current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order,
|
current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order,
|
||||||
|
@ -392,12 +391,12 @@ static void dump_header(struct oom_control *oc, struct task_struct *p,
|
||||||
|
|
||||||
cpuset_print_current_mems_allowed();
|
cpuset_print_current_mems_allowed();
|
||||||
dump_stack();
|
dump_stack();
|
||||||
if (memcg)
|
if (oc->memcg)
|
||||||
mem_cgroup_print_oom_info(memcg, p);
|
mem_cgroup_print_oom_info(oc->memcg, p);
|
||||||
else
|
else
|
||||||
show_mem(SHOW_MEM_FILTER_NODES);
|
show_mem(SHOW_MEM_FILTER_NODES);
|
||||||
if (sysctl_oom_dump_tasks)
|
if (sysctl_oom_dump_tasks)
|
||||||
dump_tasks(memcg, oc->nodemask);
|
dump_tasks(oc->memcg, oc->nodemask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -739,7 +738,7 @@ void oom_killer_enable(void)
|
||||||
*/
|
*/
|
||||||
void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
unsigned int points, unsigned long totalpages,
|
unsigned int points, unsigned long totalpages,
|
||||||
struct mem_cgroup *memcg, const char *message)
|
const char *message)
|
||||||
{
|
{
|
||||||
struct task_struct *victim = p;
|
struct task_struct *victim = p;
|
||||||
struct task_struct *child;
|
struct task_struct *child;
|
||||||
|
@ -765,7 +764,7 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
task_unlock(p);
|
task_unlock(p);
|
||||||
|
|
||||||
if (__ratelimit(&oom_rs))
|
if (__ratelimit(&oom_rs))
|
||||||
dump_header(oc, p, memcg);
|
dump_header(oc, p);
|
||||||
|
|
||||||
pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
|
pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
|
||||||
message, task_pid_nr(p), p->comm, points);
|
message, task_pid_nr(p), p->comm, points);
|
||||||
|
@ -786,8 +785,8 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
/*
|
/*
|
||||||
* oom_badness() returns 0 if the thread is unkillable
|
* oom_badness() returns 0 if the thread is unkillable
|
||||||
*/
|
*/
|
||||||
child_points = oom_badness(child, memcg, oc->nodemask,
|
child_points = oom_badness(child,
|
||||||
totalpages);
|
oc->memcg, oc->nodemask, totalpages);
|
||||||
if (child_points > victim_points) {
|
if (child_points > victim_points) {
|
||||||
put_task_struct(victim);
|
put_task_struct(victim);
|
||||||
victim = child;
|
victim = child;
|
||||||
|
@ -865,8 +864,7 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
/*
|
/*
|
||||||
* Determines whether the kernel must panic because of the panic_on_oom sysctl.
|
* Determines whether the kernel must panic because of the panic_on_oom sysctl.
|
||||||
*/
|
*/
|
||||||
void check_panic_on_oom(struct oom_control *oc, enum oom_constraint constraint,
|
void check_panic_on_oom(struct oom_control *oc, enum oom_constraint constraint)
|
||||||
struct mem_cgroup *memcg)
|
|
||||||
{
|
{
|
||||||
if (likely(!sysctl_panic_on_oom))
|
if (likely(!sysctl_panic_on_oom))
|
||||||
return;
|
return;
|
||||||
|
@ -882,7 +880,7 @@ void check_panic_on_oom(struct oom_control *oc, enum oom_constraint constraint,
|
||||||
/* Do not panic for oom kills triggered by sysrq */
|
/* Do not panic for oom kills triggered by sysrq */
|
||||||
if (is_sysrq_oom(oc))
|
if (is_sysrq_oom(oc))
|
||||||
return;
|
return;
|
||||||
dump_header(oc, NULL, memcg);
|
dump_header(oc, NULL);
|
||||||
panic("Out of memory: %s panic_on_oom is enabled\n",
|
panic("Out of memory: %s panic_on_oom is enabled\n",
|
||||||
sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide");
|
sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide");
|
||||||
}
|
}
|
||||||
|
@ -957,13 +955,13 @@ bool out_of_memory(struct oom_control *oc)
|
||||||
constraint = constrained_alloc(oc, &totalpages);
|
constraint = constrained_alloc(oc, &totalpages);
|
||||||
if (constraint != CONSTRAINT_MEMORY_POLICY)
|
if (constraint != CONSTRAINT_MEMORY_POLICY)
|
||||||
oc->nodemask = NULL;
|
oc->nodemask = NULL;
|
||||||
check_panic_on_oom(oc, constraint, NULL);
|
check_panic_on_oom(oc, constraint);
|
||||||
|
|
||||||
if (sysctl_oom_kill_allocating_task && current->mm &&
|
if (sysctl_oom_kill_allocating_task && current->mm &&
|
||||||
!oom_unkillable_task(current, NULL, oc->nodemask) &&
|
!oom_unkillable_task(current, NULL, oc->nodemask) &&
|
||||||
current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
|
current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
|
||||||
get_task_struct(current);
|
get_task_struct(current);
|
||||||
oom_kill_process(oc, current, 0, totalpages, NULL,
|
oom_kill_process(oc, current, 0, totalpages,
|
||||||
"Out of memory (oom_kill_allocating_task)");
|
"Out of memory (oom_kill_allocating_task)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -971,12 +969,11 @@ bool out_of_memory(struct oom_control *oc)
|
||||||
p = select_bad_process(oc, &points, totalpages);
|
p = select_bad_process(oc, &points, totalpages);
|
||||||
/* Found nothing?!?! Either we hang forever, or we panic. */
|
/* Found nothing?!?! Either we hang forever, or we panic. */
|
||||||
if (!p && !is_sysrq_oom(oc)) {
|
if (!p && !is_sysrq_oom(oc)) {
|
||||||
dump_header(oc, NULL, NULL);
|
dump_header(oc, NULL);
|
||||||
panic("Out of memory and no killable processes...\n");
|
panic("Out of memory and no killable processes...\n");
|
||||||
}
|
}
|
||||||
if (p && p != (void *)-1UL) {
|
if (p && p != (void *)-1UL) {
|
||||||
oom_kill_process(oc, p, points, totalpages, NULL,
|
oom_kill_process(oc, p, points, totalpages, "Out of memory");
|
||||||
"Out of memory");
|
|
||||||
/*
|
/*
|
||||||
* Give the killed process a good chance to exit before trying
|
* Give the killed process a good chance to exit before trying
|
||||||
* to allocate memory again.
|
* to allocate memory again.
|
||||||
|
@ -996,6 +993,7 @@ void pagefault_out_of_memory(void)
|
||||||
struct oom_control oc = {
|
struct oom_control oc = {
|
||||||
.zonelist = NULL,
|
.zonelist = NULL,
|
||||||
.nodemask = NULL,
|
.nodemask = NULL,
|
||||||
|
.memcg = NULL,
|
||||||
.gfp_mask = 0,
|
.gfp_mask = 0,
|
||||||
.order = 0,
|
.order = 0,
|
||||||
};
|
};
|
||||||
|
|
|
@ -3105,6 +3105,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
|
||||||
struct oom_control oc = {
|
struct oom_control oc = {
|
||||||
.zonelist = ac->zonelist,
|
.zonelist = ac->zonelist,
|
||||||
.nodemask = ac->nodemask,
|
.nodemask = ac->nodemask,
|
||||||
|
.memcg = NULL,
|
||||||
.gfp_mask = gfp_mask,
|
.gfp_mask = gfp_mask,
|
||||||
.order = order,
|
.order = order,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue