mm, oom: remove task_lock protecting comm printing
The oom killer takes task_lock() in a couple of places solely to protect printing the task's comm. A process's comm, including current's comm, may change due to /proc/pid/comm or PR_SET_NAME. The comm will always be NULL-terminated, so the worst race scenario would only be during update. We can tolerate a comm being printed that is in the middle of an update to avoid taking the lock. Other locations in the kernel have already dropped task_lock() when printing comm, so this is consistent. Signed-off-by: David Rientjes <rientjes@google.com> Suggested-by: Oleg Nesterov <oleg@redhat.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Vladimir Davydov <vdavydov@parallels.com> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
2d1e10412c
commit
da39da3a54
|
@ -93,7 +93,7 @@ extern int current_cpuset_is_being_rebound(void);
|
||||||
|
|
||||||
extern void rebuild_sched_domains(void);
|
extern void rebuild_sched_domains(void);
|
||||||
|
|
||||||
extern void cpuset_print_task_mems_allowed(struct task_struct *p);
|
extern void cpuset_print_current_mems_allowed(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read_mems_allowed_begin is required when making decisions involving
|
* read_mems_allowed_begin is required when making decisions involving
|
||||||
|
@ -219,7 +219,7 @@ static inline void rebuild_sched_domains(void)
|
||||||
partition_sched_domains(1, NULL, NULL);
|
partition_sched_domains(1, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpuset_print_task_mems_allowed(struct task_struct *p)
|
static inline void cpuset_print_current_mems_allowed(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2598,22 +2598,22 @@ int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpuset_print_task_mems_allowed - prints task's cpuset and mems_allowed
|
* cpuset_print_current_mems_allowed - prints current's cpuset and mems_allowed
|
||||||
* @tsk: pointer to task_struct of some task.
|
|
||||||
*
|
*
|
||||||
* Description: Prints @task's name, cpuset name, and cached copy of its
|
* Description: Prints current's name, cpuset name, and cached copy of its
|
||||||
* mems_allowed to the kernel log.
|
* mems_allowed to the kernel log.
|
||||||
*/
|
*/
|
||||||
void cpuset_print_task_mems_allowed(struct task_struct *tsk)
|
void cpuset_print_current_mems_allowed(void)
|
||||||
{
|
{
|
||||||
struct cgroup *cgrp;
|
struct cgroup *cgrp;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
cgrp = task_cs(tsk)->css.cgroup;
|
cgrp = task_cs(current)->css.cgroup;
|
||||||
pr_info("%s cpuset=", tsk->comm);
|
pr_info("%s cpuset=", current->comm);
|
||||||
pr_cont_cgroup_name(cgrp);
|
pr_cont_cgroup_name(cgrp);
|
||||||
pr_cont(" mems_allowed=%*pbl\n", nodemask_pr_args(&tsk->mems_allowed));
|
pr_cont(" mems_allowed=%*pbl\n",
|
||||||
|
nodemask_pr_args(¤t->mems_allowed));
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,13 +377,11 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
|
||||||
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)
|
struct mem_cgroup *memcg)
|
||||||
{
|
{
|
||||||
task_lock(current);
|
|
||||||
pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
|
pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
|
||||||
"oom_score_adj=%hd\n",
|
"oom_score_adj=%hd\n",
|
||||||
current->comm, oc->gfp_mask, oc->order,
|
current->comm, oc->gfp_mask, oc->order,
|
||||||
current->signal->oom_score_adj);
|
current->signal->oom_score_adj);
|
||||||
cpuset_print_task_mems_allowed(current);
|
cpuset_print_current_mems_allowed();
|
||||||
task_unlock(current);
|
|
||||||
dump_stack();
|
dump_stack();
|
||||||
if (memcg)
|
if (memcg)
|
||||||
mem_cgroup_print_oom_info(memcg, p);
|
mem_cgroup_print_oom_info(memcg, p);
|
||||||
|
@ -509,10 +507,8 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
if (__ratelimit(&oom_rs))
|
if (__ratelimit(&oom_rs))
|
||||||
dump_header(oc, p, memcg);
|
dump_header(oc, p, memcg);
|
||||||
|
|
||||||
task_lock(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);
|
||||||
task_unlock(p);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If any of p's children has a different mm and is eligible for kill,
|
* If any of p's children has a different mm and is eligible for kill,
|
||||||
|
@ -586,10 +582,8 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
|
||||||
if (fatal_signal_pending(p))
|
if (fatal_signal_pending(p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
task_lock(p); /* Protect ->comm from prctl() */
|
|
||||||
pr_info("Kill process %d (%s) sharing same memory\n",
|
pr_info("Kill process %d (%s) sharing same memory\n",
|
||||||
task_pid_nr(p), p->comm);
|
task_pid_nr(p), p->comm);
|
||||||
task_unlock(p);
|
|
||||||
do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true);
|
do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
Loading…
Reference in a new issue