Subject: moving SIGXCPU / autorenice handling out of mi_switch()
To: None <tech-kern@netbsd.org>
From: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
List: tech-kern
Date: 01/01/2001 12:18:02
It occurred to me as I was analyzing a MULTIPROCESSOR-related bug that
the context switch path could be streamlined by moving the "autorenice"
and "cpu time exceeded" code into schedcpu().

schedcpu() gets called once per second to recompute process
priorities, and already does some work for every process which has run
in the past second.  

Anyone see any problems with this patch?

						- Bill

Index: kern_synch.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_synch.c,v
retrieving revision 1.100
diff -u -r1.100 kern_synch.c
--- kern_synch.c	2001/01/01 16:02:51	1.100
+++ kern_synch.c	2001/01/01 17:17:13
@@ -264,6 +264,35 @@
 		 */
 		if (p->p_slptime > 1)
 			continue;
+
+		if (p->p_flag & P_INMEM) {
+			struct rlimit *rlim;
+			long rsec;
+
+			/*
+			 * Check if the process exceeds its cpu
+			 * resource allocation.  If over max, kill it.
+			 * In any case, if it has run for more than 10
+			 * minutes, reduce priority to give others a
+			 * chance.
+			 */
+			rsec = p->p_rtime.tv_sec;
+			rlim = &p->p_rlimit[RLIMIT_CPU];
+			if (rsec >= rlim->rlim_cur) {
+				if (rsec >= rlim->rlim_max)
+					psignal(p, SIGKILL);
+				else {
+					psignal(p, SIGXCPU);
+					if (rlim->rlim_cur < rlim->rlim_max)
+						rlim->rlim_cur += 5;
+				}
+			}
+			if (autonicetime && rsec > autonicetime &&
+			    p->p_ucred->cr_uid && p->p_nice == NZERO) {
+				p->p_nice = autoniceval + NZERO;
+			}
+		}
+		
 		s = splstatclock();	/* prevent state changes */
 		/*
 		 * p_pctcpu is only for ps.
@@ -767,7 +796,6 @@
 mi_switch(struct proc *p)
 {
 	struct schedstate_percpu *spc;
-	struct rlimit *rlim;
 	long s, u;
 	struct timeval tv;
 #if defined(MULTIPROCESSOR)
@@ -814,31 +842,6 @@
 	}
 	p->p_rtime.tv_usec = u;
 	p->p_rtime.tv_sec = s;
-
-	/*
-	 * Check if the process exceeds its cpu resource allocation.
-	 * If over max, kill it.  In any case, if it has run for more
-	 * than 10 minutes, reduce priority to give others a chance.
-	 */
-	rlim = &p->p_rlimit[RLIMIT_CPU];
-	if (s >= rlim->rlim_cur) {
-		/*
-		 * XXXSMP: we're inside the scheduler lock perimeter;
-		 * use sched_psignal.
-		 */
-		if (s >= rlim->rlim_max)
-			sched_psignal(p, SIGKILL);
-		else {
-			sched_psignal(p, SIGXCPU);
-			if (rlim->rlim_cur < rlim->rlim_max)
-				rlim->rlim_cur += 5;
-		}
-	}
-	if (autonicetime && s > autonicetime && p->p_ucred->cr_uid &&
-	    p->p_nice == NZERO) {
-		p->p_nice = autoniceval + NZERO;
-		resetpriority(p);
-	}
 
 	/*
 	 * Process is about to yield the CPU; clear the appropriate