Bug in p_estcpu handling on process exit in FBsd-4.x
Matthew Dillon
dillon at apollo.backplane.com
Sat Mar 20 11:41:07 PST 2004
(The same bug exists in 5.x if you use the 4BSD scheduler).
The code that causes the parent to inherit the child's p_estcpu when
the child exits is broken. It was adding the parent's and child's
p_estcpu together.
However, the child process is initialized with the parent's estcpu,
so simply adding it back in to the parent will cause the parent's
p_estcpu to blow up after only a few fork/exec's.
A better solution is to average the two, taking care to handle the
case where the child might have received one tick. This way if a
parent is exec'ing a lot of children, such as when you do a 'make',
p_estcpu will ramp-up just slightly slower then a normal cpu-bound
process would, which is exactly what we want. After all, there should
be no difference in the treatment of a single cpu-bound program verses
the treatment of a cpu-bound make which fork/exec's a lot, yet we do not
want to penalize an interactive shell that just ran a (single)
long-running cpu-bound program too much.
NOTE: this patch is against DragonFly, you may have to patch 4.x
manually. It is not a complex patch.
-Matt
Matthew Dillon
<dillon at backplane.com>
Index: kern_exit.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- kern_exit.c 18 Jan 2004 12:29:49 -0000 1.30
+++ kern_exit.c 20 Mar 2004 19:16:24 -0000 1.31
@@ -37,7 +37,7 @@
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
* $FreeBSD: src/sys/kern/kern_exit.c,v 1.92.2.11 2003/01/13 22:51:16 dillon Exp $
- * $DragonFly: src/sys/kern/kern_exit.c,v 1.30 2004/01/18 12:29:49 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_exit.c,v 1.31 2004/03/20 19:16:24 dillon Exp $
*/
#include "opt_compat.h"
@@ -468,10 +468,24 @@
}
lwkt_wait_free(p->p_thread);
- /* charge childs scheduling cpu usage to parent */
+ /*
+ * Charge the parent for the child's estimated cpu
+ * on exit to account for cpu-bound scripts that
+ * fork/exec a lot, and heavy shell use. Note that
+ * the child inherited our estcpu when it forked, so
+ * we have to undo that here. We have to add 1 to
+ * the average to deal with the case where programs
+ * take less then 1/10 second (ESTCPUFREQ) to run.
+ * Also note that we do not want to add any slop
+ * charges here since a program can fork/exec hundreds
+ * of processes a second and slop would blow p_estcpu
+ * up beyond all proportion.
+ */
if (curproc->p_pid != 1) {
- curproc->p_estcpu =
- ESTCPULIM(curproc->p_estcpu + p->p_estcpu);
+ if (p->p_estcpu > curproc->p_estcpu) {
+ curproc->p_estcpu = ESTCPULIM(
+ (p->p_estcpu + curproc->p_estcpu + 1) / 2);
+ }
}
/* Take care of our return values. */
More information about the freebsd-stable
mailing list