diff options
author | green <green@FreeBSD.org> | 2000-01-28 20:40:29 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2000-01-28 20:40:29 +0000 |
commit | cff0ff5321d20388923dae3b097c128b37160e18 (patch) | |
tree | 47f72fc9ed78759d8b2619ca5c4311a9a6c8f875 /sys/kern/kern_resource.c | |
parent | f0637b8bfa3e9e6d2c9349465fc8159e5bcfb921 (diff) | |
download | FreeBSD-src-cff0ff5321d20388923dae3b097c128b37160e18.zip FreeBSD-src-cff0ff5321d20388923dae3b097c128b37160e18.tar.gz |
Fix a bug that could crash the system if you press ^T while a slower
system is slowed down and in the right spot (a race condition in fork()).
The "previous time" fields have moved from pstat to proc. Anything which
uses KVM needs to be recompiled with a new libkvm/headers.
A couple wacky u_quad_t's in struct proc are now u_int64_t (the same, but
according to lack of 'quad's in proc.h and usage in kern_resource.c).
This will have no effect on code.
This has been make-world-and-installed-new-kernel-which-works-fine-tested.
Reviewed by: bde (previous version)
Diffstat (limited to 'sys/kern/kern_resource.c')
-rw-r--r-- | sys/kern/kern_resource.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 495175e..0307369 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -528,7 +528,7 @@ calcru(p, up, sp, ip) tu += (tv.tv_usec - switchtime.tv_usec) + (tv.tv_sec - switchtime.tv_sec) * (int64_t)1000000; } - ptu = p->p_stats->p_uu + p->p_stats->p_su + p->p_stats->p_iu; + ptu = p->p_uu + p->p_su + p->p_iu; if (tu < ptu || (int64_t)tu < 0) { /* XXX no %qd in kernel. Truncate. */ printf("calcru: negative time of %ld usec for pid %d (%s)\n", @@ -542,30 +542,29 @@ calcru(p, up, sp, ip) iu = tu - uu - su; /* Enforce monotonicity. */ - if (uu < p->p_stats->p_uu || su < p->p_stats->p_su || - iu < p->p_stats->p_iu) { - if (uu < p->p_stats->p_uu) - uu = p->p_stats->p_uu; - else if (uu + p->p_stats->p_su + p->p_stats->p_iu > tu) - uu = tu - p->p_stats->p_su - p->p_stats->p_iu; + if (uu < p->p_uu || su < p->p_su || iu < p->p_iu) { + if (uu < p->p_uu) + uu = p->p_uu; + else if (uu + p->p_su + p->p_iu > tu) + uu = tu - p->p_su - p->p_iu; if (st == 0) - su = p->p_stats->p_su; + su = p->p_su; else { su = ((tu - uu) * st) / (st + it); - if (su < p->p_stats->p_su) - su = p->p_stats->p_su; - else if (uu + su + p->p_stats->p_iu > tu) - su = tu - uu - p->p_stats->p_iu; + if (su < p->p_su) + su = p->p_su; + else if (uu + su + p->p_iu > tu) + su = tu - uu - p->p_iu; } - KASSERT(uu + su + p->p_stats->p_iu <= tu, + KASSERT(uu + su + p->p_iu <= tu, ("calcru: monotonisation botch 1")); iu = tu - uu - su; - KASSERT(iu >= p->p_stats->p_iu, + KASSERT(iu >= p->p_iu, ("calcru: monotonisation botch 2")); } - p->p_stats->p_uu = uu; - p->p_stats->p_su = su; - p->p_stats->p_iu = iu; + p->p_uu = uu; + p->p_su = su; + p->p_iu = iu; up->tv_sec = uu / 1000000; up->tv_usec = uu % 1000000; |