From: Andrea Arcangeli <andrea@suse.de>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org, Nick Piggin <npiggin@novell.com>
Subject: Re: OOM fixes 1/5
Date: Sat, 22 Jan 2005 07:35:50 +0100 [thread overview]
Message-ID: <20050122063550.GA7587@dualathlon.random> (raw)
In-Reply-To: <20050121054840.GA12647@dualathlon.random>
I noticed 1/5 had a glitch, this is an update. It won't alter the
ordering, the other patches will still apply cleanly.
Thanks.
From: garloff@suse.de
Subject: protect-pids
This is protect-pids, a patch to allow the admin to tune the oom killer.
The tweak is inherited between parent and child so it's easy to write a
wrapper for complex apps.
I made used_math a char at the light of later patches. Current patch
breaks alpha, but future patches will fix it.
Signed-off-by: Andrea Arcangeli <andrea@suse.de>
--- x/fs/proc/base.c 2005-01-15 20:44:58.000000000 +0100
+++ xx/fs/proc/base.c 2005-01-22 07:02:50.000000000 +0100
@@ -72,6 +72,8 @@ enum pid_directory_inos {
PROC_TGID_ATTR_FSCREATE,
#endif
PROC_TGID_FD_DIR,
+ PROC_TGID_OOM_SCORE,
+ PROC_TGID_OOM_ADJUST,
PROC_TID_INO,
PROC_TID_STATUS,
PROC_TID_MEM,
@@ -98,6 +100,8 @@ enum pid_directory_inos {
PROC_TID_ATTR_FSCREATE,
#endif
PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */
+ PROC_TID_OOM_SCORE,
+ PROC_TID_OOM_ADJUST,
};
struct pid_entry {
@@ -133,6 +137,8 @@ static struct pid_entry tgid_base_stuff[
#ifdef CONFIG_SCHEDSTATS
E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
#endif
+ E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
+ E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
{0,0,NULL,0}
};
static struct pid_entry tid_base_stuff[] = {
@@ -158,6 +164,8 @@ static struct pid_entry tid_base_stuff[]
#ifdef CONFIG_SCHEDSTATS
E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
#endif
+ E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
+ E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
{0,0,NULL,0}
};
@@ -384,6 +392,18 @@ static int proc_pid_schedstat(struct tas
}
#endif
+/* The badness from the OOM killer */
+unsigned long badness(struct task_struct *p, unsigned long uptime);
+static int proc_oom_score(struct task_struct *task, char *buffer)
+{
+ unsigned long points;
+ struct timespec uptime;
+
+ do_posix_clock_monotonic_gettime(&uptime);
+ points = badness(task, uptime.tv_sec);
+ return sprintf(buffer, "%lu\n", points);
+}
+
/************************************************************************/
/* Here the fs part begins */
/************************************************************************/
@@ -657,6 +677,56 @@ static struct file_operations proc_mem_o
.open = mem_open,
};
+static ssize_t oom_adjust_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task = proc_task(file->f_dentry->d_inode);
+ char buffer[8];
+ size_t len;
+ int oom_adjust = task->oomkilladj;
+ loff_t __ppos = *ppos;
+
+ len = sprintf(buffer, "%i\n", oom_adjust);
+ if (__ppos >= len)
+ return 0;
+ if (count > len-__ppos)
+ count = len-__ppos;
+ if (copy_to_user(buf, buffer + __ppos, count))
+ return -EFAULT;
+ *ppos = __ppos + count;
+ return count;
+}
+
+static ssize_t oom_adjust_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task = proc_task(file->f_dentry->d_inode);
+ char buffer[8], *end;
+ int oom_adjust;
+
+ if (!capable(CAP_SYS_RESOURCE))
+ return -EPERM;
+ memset(buffer, 0, 8);
+ if (count > 6)
+ count = 6;
+ if (copy_from_user(buffer, buf, count))
+ return -EFAULT;
+ oom_adjust = simple_strtol(buffer, &end, 0);
+ if (oom_adjust < -16 || oom_adjust > 15)
+ return -EINVAL;
+ if (*end == '\n')
+ end++;
+ task->oomkilladj = oom_adjust;
+ if (end - buffer == 0)
+ return -EIO;
+ return end - buffer;
+}
+
+static struct file_operations proc_oom_adjust_operations = {
+ read: oom_adjust_read,
+ write: oom_adjust_write,
+};
+
static struct inode_operations proc_mem_inode_operations = {
.permission = proc_permission,
};
@@ -1336,6 +1406,15 @@ static struct dentry *proc_pident_lookup
ei->op.proc_read = proc_pid_schedstat;
break;
#endif
+ case PROC_TID_OOM_SCORE:
+ case PROC_TGID_OOM_SCORE:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_oom_score;
+ break;
+ case PROC_TID_OOM_ADJUST:
+ case PROC_TGID_OOM_ADJUST:
+ inode->i_fop = &proc_oom_adjust_operations;
+ break;
default:
printk("procfs: impossible type (%d)",p->type);
iput(inode);
--- x/include/linux/sched.h 2005-01-22 07:02:29.000000000 +0100
+++ xx/include/linux/sched.h 2005-01-22 07:02:40.000000000 +0100
@@ -614,7 +614,19 @@ struct task_struct {
struct key *process_keyring; /* keyring private to this process (CLONE_THREAD) */
struct key *thread_keyring; /* keyring private to this thread */
#endif
- unsigned short used_math;
+/*
+ * Must be changed atomically so it shouldn't be
+ * be a shareable bitflag.
+ */
+ unsigned char used_math;
+/*
+ * OOM kill score adjustment (bit shift).
+ * Cannot live together with used_math since
+ * used_math and oomkilladj can be changed at the
+ * same time, so they would race if they're in the
+ * same atomic block.
+ */
+ short oomkilladj;
char comm[TASK_COMM_LEN];
/* file system info */
int link_count, total_link_count;
--- x/mm/oom_kill.c 2005-01-15 20:45:00.000000000 +0100
+++ xx/mm/oom_kill.c 2005-01-22 07:02:40.000000000 +0100
@@ -42,7 +42,7 @@
* of least surprise ... (be careful when you change it)
*/
-static unsigned long badness(struct task_struct *p, unsigned long uptime)
+unsigned long badness(struct task_struct *p, unsigned long uptime)
{
unsigned long points, cpu_time, run_time, s;
@@ -99,6 +99,17 @@ static unsigned long badness(struct task
*/
if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
points /= 4;
+
+ /*
+ * Adjust the score by oomkilladj.
+ */
+ if (p->oomkilladj) {
+ if (p->oomkilladj > 0)
+ points <<= p->oomkilladj;
+ else
+ points >>= -(p->oomkilladj);
+ }
+
#ifdef DEBUG
printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
p->pid, p->comm, points);
prev parent reply other threads:[~2005-01-22 6:36 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-21 5:48 OOM fixes 1/5 Andrea Arcangeli
2005-01-21 5:49 ` OOM fixes 2/5 Andrea Arcangeli
2005-01-21 5:49 ` OOM fixes 3/5 Andrea Arcangeli
2005-01-21 5:50 ` OOM fixes 4/5 Andrea Arcangeli
2005-01-21 5:50 ` OOM fixes 5/5 Andrea Arcangeli
2005-01-21 6:01 ` writeback-highmem Andrea Arcangeli
2005-01-21 6:26 ` writeback-highmem Andrew Morton
2005-01-21 6:41 ` writeback-highmem Andrea Arcangeli
2005-01-21 13:46 ` writeback-highmem Rik van Riel
2005-01-21 6:20 ` OOM fixes 2/5 Andrew Morton
2005-01-21 6:35 ` Andrea Arcangeli
2005-01-21 6:36 ` Nick Piggin
2005-01-21 6:46 ` Andrew Morton
2005-01-21 7:04 ` Nick Piggin
2005-01-21 7:17 ` Andrea Arcangeli
2005-01-21 7:04 ` Andrea Arcangeli
2005-01-21 7:08 ` Andi Kleen
2005-01-21 7:21 ` Andrea Arcangeli
2005-01-21 6:52 ` Andrea Arcangeli
2005-01-21 7:00 ` Andrew Morton
2005-01-21 7:10 ` Andrea Arcangeli
2005-01-22 6:35 ` Andrea Arcangeli [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050122063550.GA7587@dualathlon.random \
--to=andrea@suse.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=npiggin@novell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.