[PATCH 01/10] proc, oom: drop bogus task_lock and mm check

From: Michal Hocko
Date: Mon Jun 20 2016 - 08:44:22 EST


From: Michal Hocko <mhocko@xxxxxxxx>

both oom_adj_write and oom_score_adj_write are using task_lock,
check for task->mm and fail if it is NULL. This is not needed because
the oom_score_adj is per signal struct so we do not need mm at all.
The code has been introduced by 3d5992d2ac7d ("oom: add per-mm oom
disable count") but we do not do per-mm oom disable since c9f01245b6a7
("oom: remove oom_disable_count").

The task->mm check is even not correct because the current thread might
have exited but the thread group might be still alive - e.g. thread
group leader would lead that echo $VAL > /proc/pid/oom_score_adj would
always fail with EINVAL while /proc/pid/task/$other_tid/oom_score_adj
would succeed. This is unexpected at best.

Remove the lock along with the check to fix the unexpected behavior
and also because there is not real need for the lock in the first place.

Reviewed-by: Vladimir Davydov <vdavydov@xxxxxxxxxxxxx>
Acked-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Signed-off-by: Michal Hocko <mhocko@xxxxxxxx>
---
fs/proc/base.c | 22 ++++------------------
1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index be73f4d0cb01..a6014e45c516 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1083,15 +1083,9 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
goto out;
}

- task_lock(task);
- if (!task->mm) {
- err = -EINVAL;
- goto err_task_lock;
- }
-
if (!lock_task_sighand(task, &flags)) {
err = -ESRCH;
- goto err_task_lock;
+ goto err_put_task;
}

/*
@@ -1121,8 +1115,7 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
trace_oom_score_adj_update(task);
err_sighand:
unlock_task_sighand(task, &flags);
-err_task_lock:
- task_unlock(task);
+err_put_task:
put_task_struct(task);
out:
return err < 0 ? err : count;
@@ -1186,15 +1179,9 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
goto out;
}

- task_lock(task);
- if (!task->mm) {
- err = -EINVAL;
- goto err_task_lock;
- }
-
if (!lock_task_sighand(task, &flags)) {
err = -ESRCH;
- goto err_task_lock;
+ goto err_put_task;
}

if ((short)oom_score_adj < task->signal->oom_score_adj_min &&
@@ -1210,8 +1197,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,

err_sighand:
unlock_task_sighand(task, &flags);
-err_task_lock:
- task_unlock(task);
+err_put_task:
put_task_struct(task);
out:
return err < 0 ? err : count;
--
2.8.1