Instead of recording the Unix time in a process when it starts, record the
uptime. Where necessary, convert it back to Unix time by adding boottime to it. This fixes a potential problem in the accounting code, which would compute the elapsed time incorrectly if the Unix time was stepped during the lifetime of the process.
This commit is contained in:
parent
8fbd9bc9e9
commit
397920a125
@ -42,6 +42,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/lock.h>
|
||||
@ -129,13 +130,14 @@ procfs_doprocstatus(PFS_FILL_ARGS)
|
||||
}
|
||||
|
||||
if (p->p_sflag & PS_INMEM) {
|
||||
struct timeval ut, st;
|
||||
struct timeval start, ut, st;
|
||||
|
||||
calcru(p, &ut, &st, (struct timeval *) NULL);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
sbuf_printf(sb, " %lld,%ld %ld,%ld %ld,%ld",
|
||||
(long long)p->p_stats->p_start.tv_sec,
|
||||
p->p_stats->p_start.tv_usec,
|
||||
start = p->p_stats->p_start;
|
||||
timevaladd(&start, &boottime);
|
||||
sbuf_printf(sb, " %ld,%ld %ld,%ld %ld,%ld",
|
||||
start.tv_sec, start.tv_usec,
|
||||
ut.tv_sec, ut.tv_usec,
|
||||
st.tv_sec, st.tv_usec);
|
||||
} else {
|
||||
|
@ -467,7 +467,7 @@ proc0_post(void *dummy __unused)
|
||||
*/
|
||||
sx_slock(&allproc_lock);
|
||||
LIST_FOREACH(p, &allproc, p_list) {
|
||||
microtime(&p->p_stats->p_start);
|
||||
microuptime(&p->p_stats->p_start);
|
||||
p->p_runtime.sec = 0;
|
||||
p->p_runtime.frac = 0;
|
||||
}
|
||||
|
@ -250,8 +250,10 @@ acct_process(td)
|
||||
acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_usec);
|
||||
|
||||
/* (3) The elapsed time the command ran (and its starting time) */
|
||||
acct.ac_btime = p->p_stats->p_start.tv_sec;
|
||||
microtime(&tmp);
|
||||
tmp = boottime;
|
||||
timevaladd(&tmp, &p->p_stats->p_start);
|
||||
acct.ac_btime = tmp.tv_sec;
|
||||
microuptime(&tmp);
|
||||
timevalsub(&tmp, &p->p_stats->p_start);
|
||||
acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_usec);
|
||||
|
||||
|
@ -686,7 +686,7 @@ fork1(td, flags, pages, procp)
|
||||
* If RFSTOPPED not requested, make child runnable and add to
|
||||
* run queue.
|
||||
*/
|
||||
microtime(&(p2->p_stats->p_start));
|
||||
microuptime(&p2->p_stats->p_start);
|
||||
if ((flags & RFSTOPPED) == 0) {
|
||||
mtx_lock_spin(&sched_lock);
|
||||
p2->p_state = PRS_NORMAL;
|
||||
|
@ -79,7 +79,7 @@ kthread_create(void (*func)(void *), void *arg,
|
||||
struct thread *td;
|
||||
struct proc *p2;
|
||||
|
||||
if (!proc0.p_stats /* || proc0.p_stats->p_start.tv_sec == 0 */)
|
||||
if (!proc0.p_stats)
|
||||
panic("kthread_create called too soon");
|
||||
|
||||
error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags,
|
||||
|
@ -677,8 +677,7 @@ fill_kinfo_proc(p, kp)
|
||||
}
|
||||
if ((p->p_sflag & PS_INMEM) && p->p_stats) {
|
||||
kp->ki_start = p->p_stats->p_start;
|
||||
if (kp->ki_start.tv_sec < 3600)
|
||||
kp->ki_start.tv_sec += boottime.tv_sec;
|
||||
timevaladd(&kp->ki_start, &boottime);
|
||||
kp->ki_rusage = p->p_stats->p_ru;
|
||||
kp->ki_childtime.tv_sec = p->p_stats->p_cru.ru_utime.tv_sec +
|
||||
p->p_stats->p_cru.ru_stime.tv_sec;
|
||||
|
@ -115,6 +115,7 @@ nfs_dolock(struct vop_advlock_args *ap)
|
||||
MALLOC(p->p_nlminfo, struct nlminfo *,
|
||||
sizeof(struct nlminfo), M_LOCKF, M_WAITOK | M_ZERO);
|
||||
p->p_nlminfo->pid_start = p->p_stats->p_start;
|
||||
timevaladd(&p->p_nlminfo->pid_start, &boottime);
|
||||
}
|
||||
msg.lm_msg_ident.pid_start = p->p_nlminfo->pid_start;
|
||||
msg.lm_msg_ident.msg_seq = ++(p->p_nlminfo->msg_seq);
|
||||
|
Loading…
Reference in New Issue
Block a user