From ed6c6c586ae35c3c1da5bee8815795f80ed4eaa0 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 7 Sep 2009 09:51:23 +0000 Subject: MFC r189078: * Implement ucomm with a dynamic size function in order to print out the threads name also in the case they are not the last one shown. * On AMD64 pointers don't have enough space to be printed. Fix it. * Check a return value for malloc which wasn't checked before Sponsored by: Sandvine Incorporated --- sys/kern/kern_proc.c | 67 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 24 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index b04523bdb789..1368933e70a1 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -115,6 +115,7 @@ MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures"); static void doenterpgrp(struct proc *, struct pgrp *); static void orphanpg(struct pgrp *pg); +static void fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp); static void fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp); static void fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread); @@ -669,6 +670,30 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump) } #endif /* DDB */ +/* + * Rework the kinfo_proc members which need to be aggregated in the + * case of process-ware informations. + * Must be called with the target spinlock process held. + */ +static void +fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp) +{ + struct thread *td; + + PROC_SLOCK_ASSERT(p, MA_OWNED); + + kp->ki_estcpu = 0; + kp->ki_pctcpu = 0; + kp->ki_runtime = 0; + FOREACH_THREAD_IN_PROC(p, td) { + thread_lock(td); + kp->ki_pctcpu += sched_pctcpu(td); + kp->ki_runtime += cputick2usec(td->td_runtime); + kp->ki_estcpu += td->td_estcpu; + thread_unlock(td); + } +} + /* * Clear kinfo_proc and fill in any information that is common * to all threads in the process. @@ -868,14 +893,15 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread) kp->ki_numthreads = p->p_numthreads; kp->ki_pcb = td->td_pcb; kp->ki_kstack = (void *)td->td_kstack; - kp->ki_pctcpu = sched_pctcpu(td); - kp->ki_estcpu = td->td_estcpu; kp->ki_slptime = (ticks - td->td_slptick) / hz; kp->ki_pri.pri_class = td->td_pri_class; kp->ki_pri.pri_user = td->td_user_pri; - if (preferthread) + if (preferthread) { kp->ki_runtime = cputick2usec(td->td_runtime); + kp->ki_pctcpu = sched_pctcpu(td); + kp->ki_estcpu = td->td_estcpu; + } /* We can't get this anymore but ps etc never used it anyway. */ kp->ki_rqindex = 0; @@ -895,8 +921,9 @@ fill_kinfo_proc(struct proc *p, struct kinfo_proc *kp) fill_kinfo_proc_only(p, kp); PROC_SLOCK(p); - if (FIRST_THREAD_IN_PROC(p) != NULL) - fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp, 0); + MPASS (FIRST_THREAD_IN_PROC(p) != NULL); + fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp, 0); + fill_kinfo_aggregate(p, kp); PROC_SUNLOCK(p); } @@ -962,28 +989,20 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int flags) PROC_LOCK_ASSERT(p, MA_OWNED); - fill_kinfo_proc_only(p, &kinfo_proc); - if (flags & KERN_PROC_NOTHREADS) { - PROC_SLOCK(p); - if (FIRST_THREAD_IN_PROC(p) != NULL) - fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), - &kinfo_proc, 0); - PROC_SUNLOCK(p); + fill_kinfo_proc(p, &kinfo_proc); + if (flags & KERN_PROC_NOTHREADS) error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, - sizeof(kinfo_proc)); - } else { + sizeof(kinfo_proc)); + else { PROC_SLOCK(p); - if (FIRST_THREAD_IN_PROC(p) != NULL) - FOREACH_THREAD_IN_PROC(p, td) { - fill_kinfo_thread(td, &kinfo_proc, 1); - error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, - sizeof(kinfo_proc)); - if (error) - break; - } - else + MPASS(FIRST_THREAD_IN_PROC(p) != NULL); + FOREACH_THREAD_IN_PROC(p, td) { + fill_kinfo_thread(td, &kinfo_proc, 1); error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, - sizeof(kinfo_proc)); + sizeof(kinfo_proc)); + if (error) + break; + } PROC_SUNLOCK(p); } PROC_UNLOCK(p); -- cgit v1.3