summaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-12-08 13:17:07 +1000
committerDave Airlie <airlied@redhat.com>2012-12-10 20:03:58 +1000
commit1a1494def7eacbd25db05185aa2e81ef90892460 (patch)
tree40911f075b1fe527c6d20bf8c3070d4cdca11e97 /fs/proc
parent8de9e417757fb9f130f55a38f4ee7027b60de1c7 (diff)
parent71bfe916ebe6d026cd3d0e41c398574fc1228e03 (diff)
downloadlinux-stable-1a1494def7eacbd25db05185aa2e81ef90892460.tar.gz
linux-stable-1a1494def7eacbd25db05185aa2e81ef90892460.tar.bz2
linux-stable-1a1494def7eacbd25db05185aa2e81ef90892460.zip
Merge branch 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux into drm-next
Alex writes: Pretty minor -next pull request. We some additional new bits waiting internally for release. Hopefully Monday we can get at least some of them out. The others will probably take a few more weeks. Highlights of the current request: - ELD registers for passing audio information to the sound hardware - Handle GPUVM page faults more gracefully - Misc fixes Merge radeon test * 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux: (483 commits) drm/radeon: bump driver version for new info ioctl requests drm/radeon: fix eDP clk and lane setup for scaled modes drm/radeon: add new INFO ioctl requests drm/radeon/dce32+: use fractional fb dividers for high clocks drm/radeon: use cached memory when evicting for vram on non agp drm/radeon: add a CS flag END_OF_FRAME drm/radeon: stop page faults from hanging the system (v2) drm/radeon/dce4/5: add registers for ELD handling drm/radeon/dce3.2: add registers for ELD handling radeon: fix pll/ctrc mapping on dce2 and dce3 hardware Linux 3.7-rc7 powerpc/eeh: Do not invalidate PE properly Revert "drm/i915: enable rc6 on ilk again" ALSA: hda - Fix build without CONFIG_PM of/address: sparc: Declare of_iomap as an extern function for sparc again PM / QoS: fix wrong error-checking condition bnx2x: remove redundant warning log vxlan: fix command usage in its doc 8139cp: revert "set ring address before enabling receiver" MPI: Fix compilation on MIPS with GCC 4.4 and newer ... Conflicts: drivers/gpu/drm/exynos/exynos_drm_encoder.c drivers/gpu/drm/exynos/exynos_drm_fbdev.c drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/base.c109
1 files changed, 109 insertions, 0 deletions
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 = {
.release = mem_release,
};
+static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+ char buffer[PROC_NUMBUF];
+ int oom_adj = OOM_ADJUST_MIN;
+ size_t len;
+ unsigned long flags;
+
+ if (!task)
+ 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);
+ }
+ put_task_struct(task);
+ len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
+}
+
+static ssize_t oom_adj_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task;
+ char buffer[PROC_NUMBUF];
+ int oom_adj;
+ unsigned long flags;
+ int err;
+
+ memset(buffer, 0, sizeof(buffer));
+ if (count > sizeof(buffer) - 1)
+ count = sizeof(buffer) - 1;
+ if (copy_from_user(buffer, buf, count)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err = kstrtoint(strstrip(buffer), 0, &oom_adj);
+ if (err)
+ goto out;
+ if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) &&
+ oom_adj != OOM_DISABLE) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ task = get_proc_task(file->f_path.dentry->d_inode);
+ if (!task) {
+ err = -ESRCH;
+ 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;
+ }
+
+ /*
+ * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
+ * value is always attainable.
+ */
+ if (oom_adj == OOM_ADJUST_MAX)
+ oom_adj = OOM_SCORE_ADJ_MAX;
+ else
+ oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
+
+ if (oom_adj < task->signal->oom_score_adj &&
+ !capable(CAP_SYS_RESOURCE)) {
+ err = -EACCES;
+ goto err_sighand;
+ }
+
+ /*
+ * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
+ * /proc/pid/oom_score_adj instead.
+ */
+ printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
+ current->comm, task_pid_nr(current), task_pid_nr(task),
+ task_pid_nr(task));
+
+ task->signal->oom_score_adj = oom_adj;
+ trace_oom_score_adj_update(task);
+err_sighand:
+ unlock_task_sighand(task, &flags);
+err_task_lock:
+ task_unlock(task);
+ put_task_struct(task);
+out:
+ return err < 0 ? err : count;
+}
+
+static const struct file_operations proc_oom_adj_operations = {
+ .read = oom_adj_read,
+ .write = oom_adj_write,
+ .llseek = generic_file_llseek,
+};
+
static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),