aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c51
1 files changed, 17 insertions, 34 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2a0f5ee9b623..f7dc1050387f 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1024,23 +1024,21 @@ static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
1024 char buffer[PROC_NUMBUF]; 1024 char buffer[PROC_NUMBUF];
1025 int oom_adj = OOM_ADJUST_MIN; 1025 int oom_adj = OOM_ADJUST_MIN;
1026 size_t len; 1026 size_t len;
1027 unsigned long flags;
1028 1027
1029 if (!task) 1028 if (!task)
1030 return -ESRCH; 1029 return -ESRCH;
1031 if (lock_task_sighand(task, &flags)) { 1030 if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
1032 if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX) 1031 oom_adj = OOM_ADJUST_MAX;
1033 oom_adj = OOM_ADJUST_MAX; 1032 else
1034 else 1033 oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
1035 oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / 1034 OOM_SCORE_ADJ_MAX;
1036 OOM_SCORE_ADJ_MAX;
1037 unlock_task_sighand(task, &flags);
1038 }
1039 put_task_struct(task); 1035 put_task_struct(task);
1040 len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj); 1036 len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
1041 return simple_read_from_buffer(buf, count, ppos, buffer, len); 1037 return simple_read_from_buffer(buf, count, ppos, buffer, len);
1042} 1038}
1043 1039
1040static DEFINE_MUTEX(oom_adj_mutex);
1041
1044/* 1042/*
1045 * /proc/pid/oom_adj exists solely for backwards compatibility with previous 1043 * /proc/pid/oom_adj exists solely for backwards compatibility with previous
1046 * kernels. The effective policy is defined by oom_score_adj, which has a 1044 * kernels. The effective policy is defined by oom_score_adj, which has a
@@ -1057,7 +1055,6 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
1057 struct task_struct *task; 1055 struct task_struct *task;
1058 char buffer[PROC_NUMBUF]; 1056 char buffer[PROC_NUMBUF];
1059 int oom_adj; 1057 int oom_adj;
1060 unsigned long flags;
1061 int err; 1058 int err;
1062 1059
1063 memset(buffer, 0, sizeof(buffer)); 1060 memset(buffer, 0, sizeof(buffer));
@@ -1083,11 +1080,6 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
1083 goto out; 1080 goto out;
1084 } 1081 }
1085 1082
1086 if (!lock_task_sighand(task, &flags)) {
1087 err = -ESRCH;
1088 goto err_put_task;
1089 }
1090
1091 /* 1083 /*
1092 * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum 1084 * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
1093 * value is always attainable. 1085 * value is always attainable.
@@ -1097,10 +1089,11 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
1097 else 1089 else
1098 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; 1090 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
1099 1091
1092 mutex_lock(&oom_adj_mutex);
1100 if (oom_adj < task->signal->oom_score_adj && 1093 if (oom_adj < task->signal->oom_score_adj &&
1101 !capable(CAP_SYS_RESOURCE)) { 1094 !capable(CAP_SYS_RESOURCE)) {
1102 err = -EACCES; 1095 err = -EACCES;
1103 goto err_sighand; 1096 goto err_unlock;
1104 } 1097 }
1105 1098
1106 /* 1099 /*
@@ -1113,9 +1106,8 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
1113 1106
1114 task->signal->oom_score_adj = oom_adj; 1107 task->signal->oom_score_adj = oom_adj;
1115 trace_oom_score_adj_update(task); 1108 trace_oom_score_adj_update(task);
1116err_sighand: 1109err_unlock:
1117 unlock_task_sighand(task, &flags); 1110 mutex_unlock(&oom_adj_mutex);
1118err_put_task:
1119 put_task_struct(task); 1111 put_task_struct(task);
1120out: 1112out:
1121 return err < 0 ? err : count; 1113 return err < 0 ? err : count;
@@ -1133,15 +1125,11 @@ static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
1133 struct task_struct *task = get_proc_task(file_inode(file)); 1125 struct task_struct *task = get_proc_task(file_inode(file));
1134 char buffer[PROC_NUMBUF]; 1126 char buffer[PROC_NUMBUF];
1135 short oom_score_adj = OOM_SCORE_ADJ_MIN; 1127 short oom_score_adj = OOM_SCORE_ADJ_MIN;
1136 unsigned long flags;
1137 size_t len; 1128 size_t len;
1138 1129
1139 if (!task) 1130 if (!task)
1140 return -ESRCH; 1131 return -ESRCH;
1141 if (lock_task_sighand(task, &flags)) { 1132 oom_score_adj = task->signal->oom_score_adj;
1142 oom_score_adj = task->signal->oom_score_adj;
1143 unlock_task_sighand(task, &flags);
1144 }
1145 put_task_struct(task); 1133 put_task_struct(task);
1146 len = snprintf(buffer, sizeof(buffer), "%hd\n", oom_score_adj); 1134 len = snprintf(buffer, sizeof(buffer), "%hd\n", oom_score_adj);
1147 return simple_read_from_buffer(buf, count, ppos, buffer, len); 1135 return simple_read_from_buffer(buf, count, ppos, buffer, len);
@@ -1152,7 +1140,6 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
1152{ 1140{
1153 struct task_struct *task; 1141 struct task_struct *task;
1154 char buffer[PROC_NUMBUF]; 1142 char buffer[PROC_NUMBUF];
1155 unsigned long flags;
1156 int oom_score_adj; 1143 int oom_score_adj;
1157 int err; 1144 int err;
1158 1145
@@ -1179,25 +1166,21 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
1179 goto out; 1166 goto out;
1180 } 1167 }
1181 1168
1182 if (!lock_task_sighand(task, &flags)) { 1169 mutex_lock(&oom_adj_mutex);
1183 err = -ESRCH;
1184 goto err_put_task;
1185 }
1186
1187 if ((short)oom_score_adj < task->signal->oom_score_adj_min && 1170 if ((short)oom_score_adj < task->signal->oom_score_adj_min &&
1188 !capable(CAP_SYS_RESOURCE)) { 1171 !capable(CAP_SYS_RESOURCE)) {
1189 err = -EACCES; 1172 err = -EACCES;
1190 goto err_sighand; 1173 goto err_unlock;
1191 } 1174 }
1192 1175
1193 task->signal->oom_score_adj = (short)oom_score_adj; 1176 task->signal->oom_score_adj = (short)oom_score_adj;
1194 if (has_capability_noaudit(current, CAP_SYS_RESOURCE)) 1177 if (has_capability_noaudit(current, CAP_SYS_RESOURCE))
1195 task->signal->oom_score_adj_min = (short)oom_score_adj; 1178 task->signal->oom_score_adj_min = (short)oom_score_adj;
1179
1196 trace_oom_score_adj_update(task); 1180 trace_oom_score_adj_update(task);
1197 1181
1198err_sighand: 1182err_unlock:
1199 unlock_task_sighand(task, &flags); 1183 mutex_unlock(&oom_adj_mutex);
1200err_put_task:
1201 put_task_struct(task); 1184 put_task_struct(task);
1202out: 1185out:
1203 return err < 0 ? err : count; 1186 return err < 0 ? err : count;