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)
This commit is contained in:
Brian Feldman 2000-01-28 20:40:29 +00:00
parent a6324d7034
commit 8950d24456
3 changed files with 23 additions and 24 deletions

View File

@ -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;

View File

@ -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. */

View File

@ -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