Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Mar 2003 08:23:48 -0800
From:      Wes Peters <wes@softweyr.com>
To:        freebsd-arch@freebsd.org
Subject:   Patch to protect process from pageout killing
Message-ID:  <200303240823.48262.wes@softweyr.com>

next in thread | raw e-mail | index | archive | help
As promised, here's the patch to protect a process from being killed when 
pageout is in memory shortage.  This allows a process to specify that it 
is important enough to be skipped when pageout is looking for the largest 
process to kill.

My needs are simple.  We make a box that is a web proxy and runs from a 
memory disk, using flash for permanent storage.  The flash is mounted 
only when a configuration write is needed, the box runs from the memory 
disk.  We've experienced a problem at certain customer sites where bind 
will consume a lot (~30 MB) of ram and then pageout will kill the largest 
process, which is usually either named or squid.  This pretty much kills 
the box.  We'd much rather have pageout kill off some of the squid worker 
processes, we can recover from that.

Is this a good approach to the problem?  Feedback welcome.

--- kern/kern_resource.c.orig	Sun Mar 23 22:12:55 2003
+++ kern/kern_resource.c	Sun Mar 23 22:14:17 2003
@@ -562,12 +562,12 @@
 	}
 
 	switch (which) {
-
 	case RLIMIT_CPU:
 		mtx_lock_spin(&sched_lock);
 		p->p_cpulimit = limp->rlim_cur;
 		mtx_unlock_spin(&sched_lock);
 		break;
+
 	case RLIMIT_DATA:
 		if (limp->rlim_cur > maxdsiz)
 			limp->rlim_cur = maxdsiz;
@@ -625,6 +625,15 @@
 		if (limp->rlim_max < 1)
 			limp->rlim_max = 1;
 		break;
+
+        case RLIMIT_PROTECT:
+                mtx_lock_spin(&sched_lock);
+                if (limp->rlim_cur)
+                        p->p_flag |= P_PROTECTED;
+                else
+                        p->p_flag &= ~P_PROTECTED;
+                mtx_unlock_spin(&sched_lock);
+                break;
 	}
 	*alimp = *limp;
 	return (0);
--- sys/proc.h.orig	Sun Mar 23 21:36:13 2003
+++ sys/proc.h	Sun Mar 23 21:37:56 2003
@@ -629,6 +629,7 @@
 #define	P_EXEC		0x04000	/* Process called exec. */
 #define	P_THREADED	0x08000	/* Process is using threads. */
 #define	P_CONTINUED	0x10000	/* Proc has continued from a stopped state. 
*/
+#define	P_PROTECTED	0x20000	/* Do not kill on memory overcommit. */
 
 /* flags that control how threads may be suspended for some reason */
 #define	P_STOPPED_SIG		0x20000	/* Stopped due to SIGSTOP/SIGTSTP */
--- sys/resource.h.orig	Sun Mar 23 22:07:50 2003
+++ sys/resource.h	Sun Mar 23 22:09:45 2003
@@ -92,8 +92,9 @@
 #define	RLIMIT_NOFILE	8		/* number of open files */
 #define	RLIMIT_SBSIZE	9		/* maximum size of all socket buffers */
 #define RLIMIT_VMEM	10		/* virtual process size (inclusive of mmap) */
+#define	RLIMIT_PROTECT	11		/* protect process from overcommit kill */
 
-#define	RLIM_NLIMITS	11		/* number of resource limits */
+#define	RLIM_NLIMITS	12		/* number of resource limits */
 
 #define	RLIM_INFINITY	((rlim_t)(((u_quad_t)1 << 63) - 1))
 
@@ -115,6 +116,7 @@
 	"nofile",
 	"sbsize",
 	"vmem",
+	"protect",
 };
 #endif
 
--- vm/vm_pageout.c.orig	Sun Mar 23 21:38:19 2003
+++ vm/vm_pageout.c	Sun Mar 23 21:40:15 2003
@@ -1184,9 +1184,10 @@
 			if (PROC_TRYLOCK(p) == 0)
 				continue;
 			/*
-			 * if this is a system process, skip it
+			 * If this is a system or protected process, skip it.
 			 */
 			if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) ||
+			    (p->p_flag & P_PROTECTED) ||
 			    ((p->p_pid < 48) && (vm_swap_size != 0))) {
 				PROC_UNLOCK(p);
 				continue;


-- 

        Where am I, and what am I doing in this handbasket?

Wes Peters                                               wes@softweyr.com


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200303240823.48262.wes>