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:
parent
a6324d7034
commit
8950d24456
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user