aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/proc.txt16
-rw-r--r--fs/proc/base.c109
-rw-r--r--include/uapi/linux/oom.h9
3 files changed, 130 insertions, 4 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a1793d670cd0..3844d21d6ca3 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -33,7 +33,7 @@ Table of Contents
33 2 Modifying System Parameters 33 2 Modifying System Parameters
34 34
35 3 Per-Process Parameters 35 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
37 score 37 score
38 3.2 /proc/<pid>/oom_score - Display current oom-killer score 38 3.2 /proc/<pid>/oom_score - Display current oom-killer score
39 3.3 /proc/<pid>/io - Display the IO accounting fields 39 3.3 /proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@ of the kernel.
1320CHAPTER 3: PER-PROCESS PARAMETERS 1320CHAPTER 3: PER-PROCESS PARAMETERS
1321------------------------------------------------------------------------------ 1321------------------------------------------------------------------------------
1322 1322
13233.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score 13233.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
1324-------------------------------------------------------------------------------- 1324--------------------------------------------------------------------------------
1325 1325
1326This file can be used to adjust the badness heuristic used to select which 1326These file can be used to adjust the badness heuristic used to select which
1327process gets killed in out of memory conditions. 1327process gets killed in out of memory conditions.
1328 1328
1329The badness heuristic assigns a value to each candidate task ranging from 0 1329The 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
1361equivalent to discounting 50% of the task's allowed memory from being considered 1361equivalent to discounting 50% of the task's allowed memory from being considered
1362as scoring against the task. 1362as scoring against the task.
1363 1363
1364For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
1365be 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
1368scaled linearly with /proc/<pid>/oom_score_adj.
1369
1364The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last 1370The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
1365value set by a CAP_SYS_RESOURCE process. To reduce the value any lower 1371value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
1366requires CAP_SYS_RESOURCE. 1372requires CAP_SYS_RESOURCE.
@@ -1375,7 +1381,9 @@ minimal amount of work.
1375------------------------------------------------------------- 1381-------------------------------------------------------------
1376 1382
1377This file can be used to check the current score used by the oom-killer is for 1383This file can be used to check the current score used by the oom-killer is for
1378any given <pid>. 1384any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which
1385process should be killed in an out-of-memory situation.
1386
1379 1387
13803.3 /proc/<pid>/io - Display the IO accounting fields 13883.3 /proc/<pid>/io - Display the IO accounting fields
1381------------------------------------------------------- 1389-------------------------------------------------------
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 144a96732dd7..3c231adf8450 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = {
873 .release = mem_release, 873 .release = mem_release,
874}; 874};
875 875
876static 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
900static 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);
968err_sighand:
969 unlock_task_sighand(task, &flags);
970err_task_lock:
971 task_unlock(task);
972 put_task_struct(task);
973out:
974 return err < 0 ? err : count;
975}
976
977static 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
876static ssize_t oom_score_adj_read(struct file *file, char __user *buf, 983static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
877 size_t count, loff_t *ppos) 984 size_t count, loff_t *ppos)
878{ 985{
@@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2598 REG("cgroup", S_IRUGO, proc_cgroup_operations), 2705 REG("cgroup", S_IRUGO, proc_cgroup_operations),
2599#endif 2706#endif
2600 INF("oom_score", S_IRUGO, proc_oom_score), 2707 INF("oom_score", S_IRUGO, proc_oom_score),
2708 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
2601 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), 2709 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
2602#ifdef CONFIG_AUDITSYSCALL 2710#ifdef CONFIG_AUDITSYSCALL
2603 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), 2711 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = {
2964 REG("cgroup", S_IRUGO, proc_cgroup_operations), 3072 REG("cgroup", S_IRUGO, proc_cgroup_operations),
2965#endif 3073#endif
2966 INF("oom_score", S_IRUGO, proc_oom_score), 3074 INF("oom_score", S_IRUGO, proc_oom_score),
3075 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
2967 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), 3076 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
2968#ifdef CONFIG_AUDITSYSCALL 3077#ifdef CONFIG_AUDITSYSCALL
2969 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), 3078 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
diff --git a/include/uapi/linux/oom.h b/include/uapi/linux/oom.h
index a49c4afc7060..b29272d621ce 100644
--- a/include/uapi/linux/oom.h
+++ b/include/uapi/linux/oom.h
@@ -8,4 +8,13 @@
8#define OOM_SCORE_ADJ_MIN (-1000) 8#define OOM_SCORE_ADJ_MIN (-1000)
9#define OOM_SCORE_ADJ_MAX 1000 9#define OOM_SCORE_ADJ_MAX 1000
10 10
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
11#endif /* _UAPI__INCLUDE_LINUX_OOM_H */ 20#endif /* _UAPI__INCLUDE_LINUX_OOM_H */