Commit da39da3a authored by David Rientjes's avatar David Rientjes Committed by Linus Torvalds

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: default avatarDavid Rientjes <rientjes@google.com>
Suggested-by: default avatarOleg 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: default avatarJohannes Weiner <hannes@cmpxchg.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2d1e1041
...@@ -93,7 +93,7 @@ extern int current_cpuset_is_being_rebound(void); ...@@ -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) ...@@ -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, ...@@ -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(&current->mems_allowed));
rcu_read_unlock(); rcu_read_unlock();
} }
......
...@@ -377,13 +377,11 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask) ...@@ -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, ...@@ -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, ...@@ -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();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment