Skip to content

Commit fa0cbbf

Browse files
rientjestorvalds
authored andcommitted
mm, oom: reintroduce /proc/pid/oom_adj
This is mostly a revert of 01dc52e ("oom: remove deprecated oom_adj") from Davidlohr Bueso. It reintroduces /proc/pid/oom_adj for backwards compatibility with earlier kernels. It simply scales the value linearly when /proc/pid/oom_score_adj is written. The major difference is that its scheduled removal is no longer included in Documentation/feature-removal-schedule.txt. We do warn users with a single printk, though, to suggest the more powerful and supported /proc/pid/oom_score_adj interface. Reported-by: Artem S. Tashkinov <[email protected]> Signed-off-by: David Rientjes <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent f4bcd79 commit fa0cbbf

File tree

3 files changed

+130
-4
lines changed

3 files changed

+130
-4
lines changed

Documentation/filesystems/proc.txt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Table of Contents
3333
2 Modifying System Parameters
3434

3535
3 Per-Process Parameters
36-
3.1 /proc/<pid>/oom_score_adj - Adjust the oom-killer
36+
3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer
3737
score
3838
3.2 /proc/<pid>/oom_score - Display current oom-killer score
3939
3.3 /proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@ of the kernel.
13201320
CHAPTER 3: PER-PROCESS PARAMETERS
13211321
------------------------------------------------------------------------------
13221322

1323-
3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score
1323+
3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
13241324
--------------------------------------------------------------------------------
13251325

1326-
This file can be used to adjust the badness heuristic used to select which
1326+
These file can be used to adjust the badness heuristic used to select which
13271327
process gets killed in out of memory conditions.
13281328

13291329
The badness heuristic assigns a value to each candidate task ranging from 0
@@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least
13611361
equivalent to discounting 50% of the task's allowed memory from being considered
13621362
as scoring against the task.
13631363

1364+
For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
1365+
be used to tune the badness score. Its acceptable values range from -16
1366+
(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
1367+
(OOM_DISABLE) to disable oom killing entirely for that task. Its value is
1368+
scaled linearly with /proc/<pid>/oom_score_adj.
1369+
13641370
The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
13651371
value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
13661372
requires CAP_SYS_RESOURCE.
@@ -1375,7 +1381,9 @@ minimal amount of work.
13751381
-------------------------------------------------------------
13761382

13771383
This file can be used to check the current score used by the oom-killer is for
1378-
any given <pid>.
1384+
any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which
1385+
process should be killed in an out-of-memory situation.
1386+
13791387

13801388
3.3 /proc/<pid>/io - Display the IO accounting fields
13811389
-------------------------------------------------------

fs/proc/base.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = {
873873
.release = mem_release,
874874
};
875875

876+
static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
877+
loff_t *ppos)
878+
{
879+
struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
880+
char buffer[PROC_NUMBUF];
881+
int oom_adj = OOM_ADJUST_MIN;
882+
size_t len;
883+
unsigned long flags;
884+
885+
if (!task)
886+
return -ESRCH;
887+
if (lock_task_sighand(task, &flags)) {
888+
if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
889+
oom_adj = OOM_ADJUST_MAX;
890+
else
891+
oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
892+
OOM_SCORE_ADJ_MAX;
893+
unlock_task_sighand(task, &flags);
894+
}
895+
put_task_struct(task);
896+
len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
897+
return simple_read_from_buffer(buf, count, ppos, buffer, len);
898+
}
899+
900+
static ssize_t oom_adj_write(struct file *file, const char __user *buf,
901+
size_t count, loff_t *ppos)
902+
{
903+
struct task_struct *task;
904+
char buffer[PROC_NUMBUF];
905+
int oom_adj;
906+
unsigned long flags;
907+
int err;
908+
909+
memset(buffer, 0, sizeof(buffer));
910+
if (count > sizeof(buffer) - 1)
911+
count = sizeof(buffer) - 1;
912+
if (copy_from_user(buffer, buf, count)) {
913+
err = -EFAULT;
914+
goto out;
915+
}
916+
917+
err = kstrtoint(strstrip(buffer), 0, &oom_adj);
918+
if (err)
919+
goto out;
920+
if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) &&
921+
oom_adj != OOM_DISABLE) {
922+
err = -EINVAL;
923+
goto out;
924+
}
925+
926+
task = get_proc_task(file->f_path.dentry->d_inode);
927+
if (!task) {
928+
err = -ESRCH;
929+
goto out;
930+
}
931+
932+
task_lock(task);
933+
if (!task->mm) {
934+
err = -EINVAL;
935+
goto err_task_lock;
936+
}
937+
938+
if (!lock_task_sighand(task, &flags)) {
939+
err = -ESRCH;
940+
goto err_task_lock;
941+
}
942+
943+
/*
944+
* Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
945+
* value is always attainable.
946+
*/
947+
if (oom_adj == OOM_ADJUST_MAX)
948+
oom_adj = OOM_SCORE_ADJ_MAX;
949+
else
950+
oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
951+
952+
if (oom_adj < task->signal->oom_score_adj &&
953+
!capable(CAP_SYS_RESOURCE)) {
954+
err = -EACCES;
955+
goto err_sighand;
956+
}
957+
958+
/*
959+
* /proc/pid/oom_adj is provided for legacy purposes, ask users to use
960+
* /proc/pid/oom_score_adj instead.
961+
*/
962+
printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
963+
current->comm, task_pid_nr(current), task_pid_nr(task),
964+
task_pid_nr(task));
965+
966+
task->signal->oom_score_adj = oom_adj;
967+
trace_oom_score_adj_update(task);
968+
err_sighand:
969+
unlock_task_sighand(task, &flags);
970+
err_task_lock:
971+
task_unlock(task);
972+
put_task_struct(task);
973+
out:
974+
return err < 0 ? err : count;
975+
}
976+
977+
static const struct file_operations proc_oom_adj_operations = {
978+
.read = oom_adj_read,
979+
.write = oom_adj_write,
980+
.llseek = generic_file_llseek,
981+
};
982+
876983
static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
877984
size_t count, loff_t *ppos)
878985
{
@@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = {
25982705
REG("cgroup", S_IRUGO, proc_cgroup_operations),
25992706
#endif
26002707
INF("oom_score", S_IRUGO, proc_oom_score),
2708+
REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
26012709
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
26022710
#ifdef CONFIG_AUDITSYSCALL
26032711
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = {
29643072
REG("cgroup", S_IRUGO, proc_cgroup_operations),
29653073
#endif
29663074
INF("oom_score", S_IRUGO, proc_oom_score),
3075+
REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
29673076
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
29683077
#ifdef CONFIG_AUDITSYSCALL
29693078
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),

include/uapi/linux/oom.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,13 @@
88
#define OOM_SCORE_ADJ_MIN (-1000)
99
#define OOM_SCORE_ADJ_MAX 1000
1010

11+
/*
12+
* /proc/<pid>/oom_adj set to -17 protects from the oom killer for legacy
13+
* purposes.
14+
*/
15+
#define OOM_DISABLE (-17)
16+
/* inclusive */
17+
#define OOM_ADJUST_MIN (-16)
18+
#define OOM_ADJUST_MAX 15
19+
1120
#endif /* _UAPI__INCLUDE_LINUX_OOM_H */

0 commit comments

Comments
 (0)