|
@@ -1024,23 +1024,21 @@ static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
|
|
char buffer[PROC_NUMBUF];
|
|
char buffer[PROC_NUMBUF];
|
|
int oom_adj = OOM_ADJUST_MIN;
|
|
int oom_adj = OOM_ADJUST_MIN;
|
|
size_t len;
|
|
size_t len;
|
|
- unsigned long flags;
|
|
|
|
|
|
|
|
if (!task)
|
|
if (!task)
|
|
return -ESRCH;
|
|
return -ESRCH;
|
|
- if (lock_task_sighand(task, &flags)) {
|
|
|
|
- if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
|
|
|
|
- oom_adj = OOM_ADJUST_MAX;
|
|
|
|
- else
|
|
|
|
- oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
|
|
|
|
- OOM_SCORE_ADJ_MAX;
|
|
|
|
- unlock_task_sighand(task, &flags);
|
|
|
|
- }
|
|
|
|
|
|
+ if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
|
|
|
|
+ oom_adj = OOM_ADJUST_MAX;
|
|
|
|
+ else
|
|
|
|
+ oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
|
|
|
|
+ OOM_SCORE_ADJ_MAX;
|
|
put_task_struct(task);
|
|
put_task_struct(task);
|
|
len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
|
|
len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
|
|
return simple_read_from_buffer(buf, count, ppos, buffer, len);
|
|
return simple_read_from_buffer(buf, count, ppos, buffer, len);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static DEFINE_MUTEX(oom_adj_mutex);
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* /proc/pid/oom_adj exists solely for backwards compatibility with previous
|
|
* /proc/pid/oom_adj exists solely for backwards compatibility with previous
|
|
* kernels. The effective policy is defined by oom_score_adj, which has a
|
|
* 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,
|
|
struct task_struct *task;
|
|
struct task_struct *task;
|
|
char buffer[PROC_NUMBUF];
|
|
char buffer[PROC_NUMBUF];
|
|
int oom_adj;
|
|
int oom_adj;
|
|
- unsigned long flags;
|
|
|
|
int err;
|
|
int err;
|
|
|
|
|
|
memset(buffer, 0, sizeof(buffer));
|
|
memset(buffer, 0, sizeof(buffer));
|
|
@@ -1083,11 +1080,6 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!lock_task_sighand(task, &flags)) {
|
|
|
|
- err = -ESRCH;
|
|
|
|
- goto err_put_task;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
|
|
* Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
|
|
* value is always attainable.
|
|
* value is always attainable.
|
|
@@ -1097,10 +1089,11 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
|
|
else
|
|
else
|
|
oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
|
|
oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
|
|
|
|
|
|
|
|
+ mutex_lock(&oom_adj_mutex);
|
|
if (oom_adj < task->signal->oom_score_adj &&
|
|
if (oom_adj < task->signal->oom_score_adj &&
|
|
!capable(CAP_SYS_RESOURCE)) {
|
|
!capable(CAP_SYS_RESOURCE)) {
|
|
err = -EACCES;
|
|
err = -EACCES;
|
|
- goto err_sighand;
|
|
|
|
|
|
+ goto err_unlock;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1113,9 +1106,8 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
|
|
|
|
|
|
task->signal->oom_score_adj = oom_adj;
|
|
task->signal->oom_score_adj = oom_adj;
|
|
trace_oom_score_adj_update(task);
|
|
trace_oom_score_adj_update(task);
|
|
-err_sighand:
|
|
|
|
- unlock_task_sighand(task, &flags);
|
|
|
|
-err_put_task:
|
|
|
|
|
|
+err_unlock:
|
|
|
|
+ mutex_unlock(&oom_adj_mutex);
|
|
put_task_struct(task);
|
|
put_task_struct(task);
|
|
out:
|
|
out:
|
|
return err < 0 ? err : count;
|
|
return err < 0 ? err : count;
|
|
@@ -1133,15 +1125,11 @@ static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
|
|
struct task_struct *task = get_proc_task(file_inode(file));
|
|
struct task_struct *task = get_proc_task(file_inode(file));
|
|
char buffer[PROC_NUMBUF];
|
|
char buffer[PROC_NUMBUF];
|
|
short oom_score_adj = OOM_SCORE_ADJ_MIN;
|
|
short oom_score_adj = OOM_SCORE_ADJ_MIN;
|
|
- unsigned long flags;
|
|
|
|
size_t len;
|
|
size_t len;
|
|
|
|
|
|
if (!task)
|
|
if (!task)
|
|
return -ESRCH;
|
|
return -ESRCH;
|
|
- if (lock_task_sighand(task, &flags)) {
|
|
|
|
- oom_score_adj = task->signal->oom_score_adj;
|
|
|
|
- unlock_task_sighand(task, &flags);
|
|
|
|
- }
|
|
|
|
|
|
+ oom_score_adj = task->signal->oom_score_adj;
|
|
put_task_struct(task);
|
|
put_task_struct(task);
|
|
len = snprintf(buffer, sizeof(buffer), "%hd\n", oom_score_adj);
|
|
len = snprintf(buffer, sizeof(buffer), "%hd\n", oom_score_adj);
|
|
return simple_read_from_buffer(buf, count, ppos, buffer, len);
|
|
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,
|
|
{
|
|
{
|
|
struct task_struct *task;
|
|
struct task_struct *task;
|
|
char buffer[PROC_NUMBUF];
|
|
char buffer[PROC_NUMBUF];
|
|
- unsigned long flags;
|
|
|
|
int oom_score_adj;
|
|
int oom_score_adj;
|
|
int err;
|
|
int err;
|
|
|
|
|
|
@@ -1179,25 +1166,21 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!lock_task_sighand(task, &flags)) {
|
|
|
|
- err = -ESRCH;
|
|
|
|
- goto err_put_task;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ mutex_lock(&oom_adj_mutex);
|
|
if ((short)oom_score_adj < task->signal->oom_score_adj_min &&
|
|
if ((short)oom_score_adj < task->signal->oom_score_adj_min &&
|
|
!capable(CAP_SYS_RESOURCE)) {
|
|
!capable(CAP_SYS_RESOURCE)) {
|
|
err = -EACCES;
|
|
err = -EACCES;
|
|
- goto err_sighand;
|
|
|
|
|
|
+ goto err_unlock;
|
|
}
|
|
}
|
|
|
|
|
|
task->signal->oom_score_adj = (short)oom_score_adj;
|
|
task->signal->oom_score_adj = (short)oom_score_adj;
|
|
if (has_capability_noaudit(current, CAP_SYS_RESOURCE))
|
|
if (has_capability_noaudit(current, CAP_SYS_RESOURCE))
|
|
task->signal->oom_score_adj_min = (short)oom_score_adj;
|
|
task->signal->oom_score_adj_min = (short)oom_score_adj;
|
|
|
|
+
|
|
trace_oom_score_adj_update(task);
|
|
trace_oom_score_adj_update(task);
|
|
|
|
|
|
-err_sighand:
|
|
|
|
- unlock_task_sighand(task, &flags);
|
|
|
|
-err_put_task:
|
|
|
|
|
|
+err_unlock:
|
|
|
|
+ mutex_unlock(&oom_adj_mutex);
|
|
put_task_struct(task);
|
|
put_task_struct(task);
|
|
out:
|
|
out:
|
|
return err < 0 ? err : count;
|
|
return err < 0 ? err : count;
|