From d9d6cb99e70fa91775bbe8502650b6ded2b92db3 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 10 Jun 2004 22:11:39 +0000 Subject: [PATCH] Both 'ps' and the loadav calculations got broken by thread sleeps, which occur without knowledge by the proc and so ps/loadav thought processes sitting in e.g. accept() were in a 'R'un state when they were actually sleeping. Make ps and the loadav calculator thread-aware. --- bin/ps/print.c | 4 +++- sys/kern/kern_proc.c | 17 ++++++++++++++++- sys/kern/kern_synch.c | 21 ++++++++++++++++----- sys/kern/lwkt_msgport.c | 9 ++++++++- sys/sys/thread.h | 3 ++- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/bin/ps/print.c b/bin/ps/print.c index 55a1dd9dbd..c0aaee3989 100644 --- a/bin/ps/print.c +++ b/bin/ps/print.c @@ -32,7 +32,7 @@ * * @(#)print.c 8.6 (Berkeley) 4/16/94 * $FreeBSD: src/bin/ps/print.c,v 1.36.2.4 2002/11/30 13:00:14 tjr Exp $ - * $DragonFly: src/bin/ps/print.c,v 1.10 2004/03/19 17:47:49 cpressey Exp $ + * $DragonFly: src/bin/ps/print.c,v 1.11 2004/06/10 22:11:39 dillon Exp $ */ #include @@ -186,6 +186,8 @@ state(const KINFO *k, const VARENT *ve) case SSLEEP: if (flag & P_SINTR) /* interruptable (long) */ *cp = p->p_slptime >= MAXSLP ? 'I' : 'S'; + else if (KI_THREAD(k)->td_flags & TDF_SINTR) + *cp = 'S'; else *cp = 'D'; break; diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index f4c7864836..1df9ad260e 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -32,7 +32,7 @@ * * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 * $FreeBSD: src/sys/kern/kern_proc.c,v 1.63.2.9 2003/05/08 07:47:16 kbyanc Exp $ - * $DragonFly: src/sys/kern/kern_proc.c,v 1.14 2004/05/29 02:47:50 dillon Exp $ + * $DragonFly: src/sys/kern/kern_proc.c,v 1.15 2004/06/10 22:11:35 dillon Exp $ */ #include @@ -460,6 +460,21 @@ sysctl_out_proc(struct proc *p, struct thread *td, struct sysctl_req *req, int d td = p->p_thread; fill_eproc(p, &eproc); xproc = *p; + + /* + * Fixup p_stat from SRUN to SSLEEP if the process scheduler + * does not own the process and the thread scheduler says it + * isn't running or runnable. + * + * XXX temporary fix which might become permanent (I'd rather + * not pollute the thread scheduler with knowlege about + * processes). + */ + if ((p->p_flag & P_CP_RELEASED) && p->p_stat == SRUN && + td && (td->td_flags & (TDF_RUNNING|TDF_RUNQ)) == 0 + ) { + xproc.p_stat = SSLEEP; + } } else if (td) { fill_eproc_td(td, &eproc, &xproc); } diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index aa5d2b49a4..a235d75f9c 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -37,7 +37,7 @@ * * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 * $FreeBSD: src/sys/kern/kern_synch.c,v 1.87.2.6 2002/10/13 07:29:53 kbyanc Exp $ - * $DragonFly: src/sys/kern/kern_synch.c,v 1.32 2004/04/10 20:55:23 dillon Exp $ + * $DragonFly: src/sys/kern/kern_synch.c,v 1.33 2004/06/10 22:11:35 dillon Exp $ */ #include "opt_ktrace.h" @@ -744,10 +744,21 @@ loadav(void *arg) avg = &averunnable; nrun = 0; FOREACH_PROC_IN_SYSTEM(p) { - switch (p->p_stat) { - case SRUN: - case SIDL: - nrun++; + thread_t td; + if (p->p_flag & P_CP_RELEASED) { + if ((td = p->p_thread) != NULL) { + if (td->td_flags & (TDF_RUNQ|TDF_RUNNING)) + nrun++; + } + } else { + switch (p->p_stat) { + case SRUN: + case SIDL: + nrun++; + break; + default: + break; + } } } for (i = 0; i < 3; i++) diff --git a/sys/kern/lwkt_msgport.c b/sys/kern/lwkt_msgport.c index 70161f759d..a3eeba96a2 100644 --- a/sys/kern/lwkt_msgport.c +++ b/sys/kern/lwkt_msgport.c @@ -26,7 +26,7 @@ * NOTE! This file may be compiled for userland libraries as well as for * the kernel. * - * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.23 2004/06/07 07:01:34 dillon Exp $ + * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.24 2004/06/10 22:11:35 dillon Exp $ */ #ifdef _KERNEL @@ -621,8 +621,15 @@ lwkt_default_waitport(lwkt_port_t port, lwkt_msg_t msg) } } #endif + /* + * XXX set TDF_SINTR so 'ps' knows the difference between + * an interruptable wait and a disk wait. YYY eventually + * move P_SINTR to TDF_SINTR to reduce duplication. + */ + td->td_flags |= TDF_SINTR; lwkt_deschedule_self(td); lwkt_switch(); + td->td_flags &= ~TDF_SINTR; } while ((msg->ms_flags & MSGF_DONE) == 0); port->mp_flags &= ~MSGPORTF_WAITING; /* saved by the BGL */ } diff --git a/sys/sys/thread.h b/sys/sys/thread.h index e4dab098bb..756042258a 100644 --- a/sys/sys/thread.h +++ b/sys/sys/thread.h @@ -7,7 +7,7 @@ * Types which must already be defined when this header is included by * userland: struct md_thread * - * $DragonFly: src/sys/sys/thread.h,v 1.52 2004/05/28 08:37:32 dillon Exp $ + * $DragonFly: src/sys/sys/thread.h,v 1.53 2004/06/10 22:11:36 dillon Exp $ */ #ifndef _SYS_THREAD_H_ @@ -257,6 +257,7 @@ struct thread { #define TDF_PREEMPT_DONE 0x0008 /* acknowledge preemption complete */ #define TDF_IDLE_NOHLT 0x0010 /* we need to spin */ #define TDF_MIGRATING 0x0020 /* thread is being migrated */ +#define TDF_SINTR 0x0040 /* interruptability hint for 'ps' */ #define TDF_SYSTHREAD 0x0100 /* system thread */ #define TDF_ALLOCATED_THREAD 0x0200 /* zalloc allocated thread */ -- 2.41.0