[RFC][PATCH] Add support for oom_score_adj

Marc - A. Dahlhaus mad at wol.de
Sun Mar 13 18:29:32 UTC 2011


Hello List

I've added support for the oom_score_adj procfs file to upstart 1.0.

The old oom_adj procfs interface is deprecated and scheduled for removal.

Also usage of the old interface pollutes dmesg with warning messages.

I'll send updates for the test suite when this patch is in an acceptable form.

Please review and comment on the patch.

Thanks,

Marc

Signed-off-by: Marc - A. Dahlhaus <mad at wol.de>
--- a/init/errors.h
+++ b/init/errors.h
@@ -62,7 +62,8 @@ enum {
 #define PARSE_ILLEGAL_EXIT_STR		N_("Illegal exit status, expected integer")
 #define PARSE_ILLEGAL_UMASK_STR		N_("Illegal file creation mask, expected octal integer")
 #define PARSE_ILLEGAL_NICE_STR		N_("Illegal nice value, expected -20 to 19")
-#define PARSE_ILLEGAL_OOM_STR		N_("Illegal oom adjustment, expected -16 to 15 or never")
+#define PARSE_ILLEGAL_OOM_STR		N_("Illegal oom adjustment, expected -16 to 15 or 'never'")
+#define PARSE_ILLEGAL_OOM_SCORE_STR	N_("Illegal oom score adjustment, expected -999 to 1000 or 'never'")
 #define PARSE_ILLEGAL_LIMIT_STR		N_("Illegal limit, expected 'unlimited' or integer")
 #define PARSE_EXPECTED_EVENT_STR	N_("Expected event")
 #define PARSE_EXPECTED_OPERATOR_STR	N_("Expected operator")
--- a/init/job_class.c
+++ b/init/job_class.c
@@ -212,6 +212,7 @@ job_class_new (const void *parent,
 	class->umask = JOB_DEFAULT_UMASK;
 	class->nice = 0;
 	class->oom_adj = 0;
+	class->oom_score_adj = 0;
 
 	for (i = 0; i < RLIMIT_NLIMITS; i++)
 		class->limits[i] = NULL;
--- a/init/job_class.h
+++ b/init/job_class.h
@@ -94,6 +94,7 @@ typedef enum console_type {
  * @umask: file mode creation mask,
  * @nice: process priority,
  * @oom_adj: OOM killer adjustment,
+ * @oom_score_adj: OOM killer score adjustment,
  * @limits: resource limits indexed by resource,
  * @chroot: root directory of process (implies @chdir if not set),
  * @chdir: working directory of process,
@@ -142,6 +143,7 @@ typedef struct job_class {
 	mode_t          umask;
 	int             nice;
 	int             oom_adj;
+	int             oom_score_adj;
 	struct rlimit  *limits[RLIMIT_NLIMITS];
 	char           *chroot;
 	char           *chdir;
--- a/init/job_process.c
+++ b/init/job_process.c
@@ -363,7 +363,7 @@ job_process_spawn (JobClass     *class,
 {
 	sigset_t  child_set, orig_set;
 	pid_t     pid;
-	int       i, fds[2];
+	int       i, fds[2], oom_value;
 	char      filename[PATH_MAX];
 	FILE     *fd;
 
@@ -487,14 +487,20 @@ job_process_spawn (JobClass     *class,
 	 */
 	if (class->oom_adj) {
 		snprintf (filename, sizeof (filename),
-			  "/proc/%d/oom_adj", getpid ());
-
+			  "/proc/%d/oom_score_adj", getpid ());
+		oom_value = class->oom_score_adj;
 		fd = fopen (filename, "w");
 		if (! fd) {
+			snprintf (filename, sizeof (filename),
+				  "/proc/%d/oom_adj", getpid ());
+			oom_value = class->oom_adj;
+			fd = fopen (filename, "w");
+		}
+		if (! fd) {
 			nih_error_raise_system ();
 			job_process_error_abort (fds[1], JOB_PROCESS_ERROR_OOM_ADJ, 0);
 		} else {
-			fprintf (fd, "%d\n", class->oom_adj);
+			fprintf (fd, "%d\n", oom_value);
 
 			if (fclose (fd)) {
 				nih_error_raise_system ();
--- a/init/parse_job.c
+++ b/init/parse_job.c
@@ -2247,12 +2247,43 @@ stanza_oom (JobClass        *class,
 	if (! arg)
 		goto finish;
 
+	if (! strcmp (arg, "score")) {
+		nih_local char *scorearg = NULL;
+
+		scorearg = nih_config_next_arg (NULL, file, len,
+						&a_pos, &a_lineno);
+		if (! scorearg)
+			goto finish;
+
+		if (! strcmp (scorearg, "never")) {
+			class->oom_score_adj = -1000;
+			class->oom_adj = -17;
+		} else {
+			errno = 0;
+			class->oom_score_adj = (int)strtol (scorearg, &endptr, 10);
+			if (class->oom_adj == 0) {
+				class->oom_adj = (class->oom_score_adj * 16) / 1000;
+				if (class->oom_adj > 15)
+					class->oom_adj = 15;
+			}
+			if (errno || *endptr ||
+			    (class->oom_score_adj < -1000) ||
+			    (class->oom_score_adj > 1000))
+				nih_return_error (-1, PARSE_ILLEGAL_OOM,
+						  _(PARSE_ILLEGAL_OOM_SCORE_STR));
+		}
+	}
+
 	if (! strcmp (arg, "never")) {
 		class->oom_adj = -17;
+		class->oom_score_adj = -1000;
 	} else {
 		errno = 0;
 		class->oom_adj = (int)strtol (arg, &endptr, 10);
-		if (errno || *endptr || (class->oom_adj < -17) || (class->oom_adj > 15))
+		if (class->oom_score_adj == 0)
+			class->oom_score_adj = (class->oom_adj * 1000) / 17;
+		if (errno || *endptr || (class->oom_adj < -17) ||
+		    (class->oom_adj > 15))
 			nih_return_error (-1, PARSE_ILLEGAL_OOM,
 					  _(PARSE_ILLEGAL_OOM_STR));
 	}




More information about the upstart-devel mailing list