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 | |
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)
-rw-r--r-- | sys/kern/kern_resource.c | 33 | ||||
-rw-r--r-- | sys/sys/proc.h | 11 | ||||
-rw-r--r-- | sys/sys/resourcevar.h | 3 |
3 files changed, 23 insertions, 24 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; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index f6af6d9..4c2eead 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -172,10 +172,13 @@ struct proc { u_int p_slptime; /* Time since last blocked. */ struct itimerval p_realtimer; /* Alarm timer. */ - u_int64_t p_runtime; /* Real time in microsec. */ - u_quad_t p_uticks; /* Statclock hits in user mode. */ - u_quad_t p_sticks; /* Statclock hits in system mode. */ - u_quad_t p_iticks; /* Statclock hits processing intr. */ + u_int64_t p_runtime; /* Real time in microsec. */ + u_int64_t p_uu; /* Previous user time in microsec. */ + u_int64_t p_su; /* Previous system time in microsec. */ + u_int64_t p_iu; /* Previous interrupt time in usec. */ + u_int64_t p_uticks; /* Statclock hits in user mode. */ + u_int64_t p_sticks; /* Statclock hits in system mode. */ + u_int64_t p_iticks; /* Statclock hits processing intr. */ int p_traceflag; /* Kernel trace points. */ struct vnode *p_tracep; /* Trace to vnode. */ diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h index 92ed5bf..75a8f53 100644 --- a/sys/sys/resourcevar.h +++ b/sys/sys/resourcevar.h @@ -47,9 +47,6 @@ struct pstats { #define pstat_startzero p_ru struct rusage p_ru; /* stats for this proc */ struct rusage p_cru; /* sum of stats for reaped children */ - u_int64_t p_uu; /* previous user time (us) */ - u_int64_t p_su; /* previous system time (us) */ - u_int64_t p_iu; /* previous interrupt time (us) */ #define pstat_endzero pstat_startcopy #define pstat_startcopy p_timer |