1bea45cddSEd Schouten /*- 251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 351369649SPedro F. Giffuni * 4bea45cddSEd Schouten * Copyright (c) 1982, 1986, 1990, 1991, 1993 5bea45cddSEd Schouten * The Regents of the University of California. All rights reserved. 6bea45cddSEd Schouten * (c) UNIX System Laboratories, Inc. 7bea45cddSEd Schouten * All or some portions of this file are derived from material licensed 8bea45cddSEd Schouten * to the University of California by American Telephone and Telegraph 9bea45cddSEd Schouten * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10bea45cddSEd Schouten * the permission of UNIX System Laboratories, Inc. 11bea45cddSEd Schouten * 12bea45cddSEd Schouten * Copyright (c) 2002 Networks Associates Technologies, Inc. 13bea45cddSEd Schouten * All rights reserved. 14bea45cddSEd Schouten * 15bea45cddSEd Schouten * Portions of this software were developed for the FreeBSD Project by 16bea45cddSEd Schouten * ThinkSec AS and NAI Labs, the Security Research Division of Network 17bea45cddSEd Schouten * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 18bea45cddSEd Schouten * ("CBOSS"), as part of the DARPA CHATS research program. 19bea45cddSEd Schouten * 20bea45cddSEd Schouten * Redistribution and use in source and binary forms, with or without 21bea45cddSEd Schouten * modification, are permitted provided that the following conditions 22bea45cddSEd Schouten * are met: 23bea45cddSEd Schouten * 1. Redistributions of source code must retain the above copyright 24bea45cddSEd Schouten * notice, this list of conditions and the following disclaimer. 25bea45cddSEd Schouten * 2. Redistributions in binary form must reproduce the above copyright 26bea45cddSEd Schouten * notice, this list of conditions and the following disclaimer in the 27bea45cddSEd Schouten * documentation and/or other materials provided with the distribution. 2869a28758SEd Maste * 3. Neither the name of the University nor the names of its contributors 29bea45cddSEd Schouten * may be used to endorse or promote products derived from this software 30bea45cddSEd Schouten * without specific prior written permission. 31bea45cddSEd Schouten * 32bea45cddSEd Schouten * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33bea45cddSEd Schouten * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34bea45cddSEd Schouten * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35bea45cddSEd Schouten * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36bea45cddSEd Schouten * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37bea45cddSEd Schouten * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38bea45cddSEd Schouten * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39bea45cddSEd Schouten * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40bea45cddSEd Schouten * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41bea45cddSEd Schouten * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42bea45cddSEd Schouten * SUCH DAMAGE. 43bea45cddSEd Schouten */ 44bea45cddSEd Schouten 45bea45cddSEd Schouten #include <sys/cdefs.h> 46bea45cddSEd Schouten __FBSDID("$FreeBSD$"); 47bea45cddSEd Schouten 48bea45cddSEd Schouten #include <sys/param.h> 49*6858c2ccSConrad Meyer #include <sys/cons.h> 50*6858c2ccSConrad Meyer #include <sys/kdb.h> 51bea45cddSEd Schouten #include <sys/lock.h> 52bea45cddSEd Schouten #include <sys/mutex.h> 53bea45cddSEd Schouten #include <sys/proc.h> 54bea45cddSEd Schouten #include <sys/resourcevar.h> 55*6858c2ccSConrad Meyer #include <sys/sbuf.h> 56bea45cddSEd Schouten #include <sys/sched.h> 57bea45cddSEd Schouten #include <sys/systm.h> 58bea45cddSEd Schouten #include <sys/tty.h> 59bea45cddSEd Schouten 60bea45cddSEd Schouten #include <vm/vm.h> 61bea45cddSEd Schouten #include <vm/pmap.h> 62bea45cddSEd Schouten #include <vm/vm_map.h> 63bea45cddSEd Schouten 64bea45cddSEd Schouten /* 65bea45cddSEd Schouten * Returns 1 if p2 is "better" than p1 66bea45cddSEd Schouten * 67bea45cddSEd Schouten * The algorithm for picking the "interesting" process is thus: 68bea45cddSEd Schouten * 69bea45cddSEd Schouten * 1) Only foreground processes are eligible - implied. 70bea45cddSEd Schouten * 2) Runnable processes are favored over anything else. The runner 71bea45cddSEd Schouten * with the highest cpu utilization is picked (p_estcpu). Ties are 72bea45cddSEd Schouten * broken by picking the highest pid. 73bea45cddSEd Schouten * 3) The sleeper with the shortest sleep time is next. With ties, 74bea45cddSEd Schouten * we pick out just "short-term" sleepers (P_SINTR == 0). 75bea45cddSEd Schouten * 4) Further ties are broken by picking the highest pid. 76bea45cddSEd Schouten */ 77bea45cddSEd Schouten 78bea45cddSEd Schouten #define TESTAB(a, b) ((a)<<1 | (b)) 79bea45cddSEd Schouten #define ONLYA 2 80bea45cddSEd Schouten #define ONLYB 1 81bea45cddSEd Schouten #define BOTH 3 82bea45cddSEd Schouten 83bea45cddSEd Schouten static int 849e577585SEd Schouten proc_sum(struct proc *p, fixpt_t *estcpup) 85bea45cddSEd Schouten { 86bea45cddSEd Schouten struct thread *td; 87bea45cddSEd Schouten int estcpu; 88bea45cddSEd Schouten int val; 89bea45cddSEd Schouten 90bea45cddSEd Schouten val = 0; 91bea45cddSEd Schouten estcpu = 0; 92bea45cddSEd Schouten FOREACH_THREAD_IN_PROC(p, td) { 93bea45cddSEd Schouten thread_lock(td); 94bea45cddSEd Schouten if (TD_ON_RUNQ(td) || 95bea45cddSEd Schouten TD_IS_RUNNING(td)) 96bea45cddSEd Schouten val = 1; 97bea45cddSEd Schouten estcpu += sched_pctcpu(td); 98bea45cddSEd Schouten thread_unlock(td); 99bea45cddSEd Schouten } 100bea45cddSEd Schouten *estcpup = estcpu; 101bea45cddSEd Schouten 102bea45cddSEd Schouten return (val); 103bea45cddSEd Schouten } 104bea45cddSEd Schouten 105bea45cddSEd Schouten static int 106bea45cddSEd Schouten thread_compare(struct thread *td, struct thread *td2) 107bea45cddSEd Schouten { 108bea45cddSEd Schouten int runa, runb; 109bea45cddSEd Schouten int slpa, slpb; 110bea45cddSEd Schouten fixpt_t esta, estb; 111bea45cddSEd Schouten 112bea45cddSEd Schouten if (td == NULL) 113bea45cddSEd Schouten return (1); 114bea45cddSEd Schouten 115bea45cddSEd Schouten /* 116bea45cddSEd Schouten * Fetch running stats, pctcpu usage, and interruptable flag. 117bea45cddSEd Schouten */ 118bea45cddSEd Schouten thread_lock(td); 119bea45cddSEd Schouten runa = TD_IS_RUNNING(td) | TD_ON_RUNQ(td); 120bea45cddSEd Schouten slpa = td->td_flags & TDF_SINTR; 121bea45cddSEd Schouten esta = sched_pctcpu(td); 122bea45cddSEd Schouten thread_unlock(td); 123bea45cddSEd Schouten thread_lock(td2); 124bea45cddSEd Schouten runb = TD_IS_RUNNING(td2) | TD_ON_RUNQ(td2); 125bea45cddSEd Schouten estb = sched_pctcpu(td2); 126bea45cddSEd Schouten slpb = td2->td_flags & TDF_SINTR; 127bea45cddSEd Schouten thread_unlock(td2); 128bea45cddSEd Schouten /* 129bea45cddSEd Schouten * see if at least one of them is runnable 130bea45cddSEd Schouten */ 131bea45cddSEd Schouten switch (TESTAB(runa, runb)) { 132bea45cddSEd Schouten case ONLYA: 133bea45cddSEd Schouten return (0); 134bea45cddSEd Schouten case ONLYB: 135bea45cddSEd Schouten return (1); 136bea45cddSEd Schouten case BOTH: 137bea45cddSEd Schouten break; 138bea45cddSEd Schouten } 139bea45cddSEd Schouten /* 140bea45cddSEd Schouten * favor one with highest recent cpu utilization 141bea45cddSEd Schouten */ 142bea45cddSEd Schouten if (estb > esta) 143bea45cddSEd Schouten return (1); 144bea45cddSEd Schouten if (esta > estb) 145bea45cddSEd Schouten return (0); 146bea45cddSEd Schouten /* 147bea45cddSEd Schouten * favor one sleeping in a non-interruptible sleep 148bea45cddSEd Schouten */ 149bea45cddSEd Schouten switch (TESTAB(slpa, slpb)) { 150bea45cddSEd Schouten case ONLYA: 151bea45cddSEd Schouten return (0); 152bea45cddSEd Schouten case ONLYB: 153bea45cddSEd Schouten return (1); 154bea45cddSEd Schouten case BOTH: 155bea45cddSEd Schouten break; 156bea45cddSEd Schouten } 157bea45cddSEd Schouten 158bea45cddSEd Schouten return (td < td2); 159bea45cddSEd Schouten } 160bea45cddSEd Schouten 161bea45cddSEd Schouten static int 162bea45cddSEd Schouten proc_compare(struct proc *p1, struct proc *p2) 163bea45cddSEd Schouten { 164bea45cddSEd Schouten 165bea45cddSEd Schouten int runa, runb; 166bea45cddSEd Schouten fixpt_t esta, estb; 167bea45cddSEd Schouten 168bea45cddSEd Schouten if (p1 == NULL) 169bea45cddSEd Schouten return (1); 170bea45cddSEd Schouten 171bea45cddSEd Schouten /* 172bea45cddSEd Schouten * Fetch various stats about these processes. After we drop the 173bea45cddSEd Schouten * lock the information could be stale but the race is unimportant. 174bea45cddSEd Schouten */ 175bea45cddSEd Schouten PROC_LOCK(p1); 176bea45cddSEd Schouten runa = proc_sum(p1, &esta); 177bea45cddSEd Schouten PROC_UNLOCK(p1); 178bea45cddSEd Schouten PROC_LOCK(p2); 179bea45cddSEd Schouten runb = proc_sum(p2, &estb); 180bea45cddSEd Schouten PROC_UNLOCK(p2); 181bea45cddSEd Schouten 182bea45cddSEd Schouten /* 183bea45cddSEd Schouten * see if at least one of them is runnable 184bea45cddSEd Schouten */ 185bea45cddSEd Schouten switch (TESTAB(runa, runb)) { 186bea45cddSEd Schouten case ONLYA: 187bea45cddSEd Schouten return (0); 188bea45cddSEd Schouten case ONLYB: 189bea45cddSEd Schouten return (1); 190bea45cddSEd Schouten case BOTH: 191bea45cddSEd Schouten break; 192bea45cddSEd Schouten } 193bea45cddSEd Schouten /* 194bea45cddSEd Schouten * favor one with highest recent cpu utilization 195bea45cddSEd Schouten */ 196bea45cddSEd Schouten if (estb > esta) 197bea45cddSEd Schouten return (1); 198bea45cddSEd Schouten if (esta > estb) 199bea45cddSEd Schouten return (0); 200bea45cddSEd Schouten /* 201bea45cddSEd Schouten * weed out zombies 202bea45cddSEd Schouten */ 203bea45cddSEd Schouten switch (TESTAB(p1->p_state == PRS_ZOMBIE, p2->p_state == PRS_ZOMBIE)) { 204bea45cddSEd Schouten case ONLYA: 205bea45cddSEd Schouten return (1); 206bea45cddSEd Schouten case ONLYB: 207bea45cddSEd Schouten return (0); 208bea45cddSEd Schouten case BOTH: 209bea45cddSEd Schouten break; 210bea45cddSEd Schouten } 211bea45cddSEd Schouten 212bea45cddSEd Schouten return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 213bea45cddSEd Schouten } 214bea45cddSEd Schouten 215*6858c2ccSConrad Meyer static int 216*6858c2ccSConrad Meyer sbuf_tty_drain(void *a, const char *d, int len) 217*6858c2ccSConrad Meyer { 218*6858c2ccSConrad Meyer struct tty *tp; 219*6858c2ccSConrad Meyer int rc; 220*6858c2ccSConrad Meyer 221*6858c2ccSConrad Meyer tp = a; 222*6858c2ccSConrad Meyer 223*6858c2ccSConrad Meyer if (kdb_active) { 224*6858c2ccSConrad Meyer cnputsn(d, len); 225*6858c2ccSConrad Meyer return (len); 226*6858c2ccSConrad Meyer } 227*6858c2ccSConrad Meyer if (tp != NULL && panicstr == NULL) { 228*6858c2ccSConrad Meyer rc = tty_putstrn(tp, d, len); 229*6858c2ccSConrad Meyer if (rc != 0) 230*6858c2ccSConrad Meyer return (-ENXIO); 231*6858c2ccSConrad Meyer return (len); 232*6858c2ccSConrad Meyer } 233*6858c2ccSConrad Meyer return (-ENXIO); 234*6858c2ccSConrad Meyer } 235*6858c2ccSConrad Meyer 236bea45cddSEd Schouten /* 237bea45cddSEd Schouten * Report on state of foreground process group. 238bea45cddSEd Schouten */ 239bea45cddSEd Schouten void 240bc093719SEd Schouten tty_info(struct tty *tp) 241bea45cddSEd Schouten { 242dd970f41SEd Schouten struct timeval rtime, utime, stime; 243dd970f41SEd Schouten struct proc *p, *ppick; 244dd970f41SEd Schouten struct thread *td, *tdpick; 245bea45cddSEd Schouten const char *stateprefix, *state; 246*6858c2ccSConrad Meyer struct sbuf sb; 247bea45cddSEd Schouten long rss; 248bea45cddSEd Schouten int load, pctcpu; 249bea45cddSEd Schouten pid_t pid; 250bea45cddSEd Schouten char comm[MAXCOMLEN + 1]; 251bea45cddSEd Schouten struct rusage ru; 252bea45cddSEd Schouten 253bc093719SEd Schouten tty_lock_assert(tp, MA_OWNED); 254bc093719SEd Schouten 255bc093719SEd Schouten if (tty_checkoutq(tp) == 0) 256bea45cddSEd Schouten return; 257bea45cddSEd Schouten 258*6858c2ccSConrad Meyer (void)sbuf_new(&sb, tp->t_prbuf, sizeof(tp->t_prbuf), SBUF_FIXEDLEN); 259*6858c2ccSConrad Meyer sbuf_set_drain(&sb, sbuf_tty_drain, tp); 260*6858c2ccSConrad Meyer 261bea45cddSEd Schouten /* Print load average. */ 262bea45cddSEd Schouten load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 263*6858c2ccSConrad Meyer sbuf_printf(&sb, "%sload: %d.%02d ", tp->t_column == 0 ? "" : "\n", 264379affd5SEd Schouten load / 100, load % 100); 265bea45cddSEd Schouten 266bea45cddSEd Schouten if (tp->t_session == NULL) { 267*6858c2ccSConrad Meyer sbuf_printf(&sb, "not a controlling terminal\n"); 268*6858c2ccSConrad Meyer goto out; 269bea45cddSEd Schouten } 270bea45cddSEd Schouten if (tp->t_pgrp == NULL) { 271*6858c2ccSConrad Meyer sbuf_printf(&sb, "no foreground process group\n"); 272*6858c2ccSConrad Meyer goto out; 273bea45cddSEd Schouten } 274bea45cddSEd Schouten PGRP_LOCK(tp->t_pgrp); 275bea45cddSEd Schouten if (LIST_EMPTY(&tp->t_pgrp->pg_members)) { 276bea45cddSEd Schouten PGRP_UNLOCK(tp->t_pgrp); 277*6858c2ccSConrad Meyer sbuf_printf(&sb, "empty foreground process group\n"); 278*6858c2ccSConrad Meyer goto out; 279bea45cddSEd Schouten } 280bea45cddSEd Schouten 281bea45cddSEd Schouten /* 282bea45cddSEd Schouten * Pick the most interesting process and copy some of its 283bea45cddSEd Schouten * state for printing later. This operation could rely on stale 284bea45cddSEd Schouten * data as we can't hold the proc slock or thread locks over the 285bea45cddSEd Schouten * whole list. However, we're guaranteed not to reference an exited 286bea45cddSEd Schouten * thread or proc since we hold the tty locked. 287bea45cddSEd Schouten */ 288dd970f41SEd Schouten p = NULL; 289dd970f41SEd Schouten LIST_FOREACH(ppick, &tp->t_pgrp->pg_members, p_pglist) 290dd970f41SEd Schouten if (proc_compare(p, ppick)) 291dd970f41SEd Schouten p = ppick; 292bea45cddSEd Schouten 293dd970f41SEd Schouten PROC_LOCK(p); 294dd970f41SEd Schouten PGRP_UNLOCK(tp->t_pgrp); 295dd970f41SEd Schouten td = NULL; 296dd970f41SEd Schouten FOREACH_THREAD_IN_PROC(p, tdpick) 297dd970f41SEd Schouten if (thread_compare(td, tdpick)) 298dd970f41SEd Schouten td = tdpick; 299bea45cddSEd Schouten stateprefix = ""; 300bea45cddSEd Schouten thread_lock(td); 301bea45cddSEd Schouten if (TD_IS_RUNNING(td)) 302bea45cddSEd Schouten state = "running"; 303bea45cddSEd Schouten else if (TD_ON_RUNQ(td) || TD_CAN_RUN(td)) 304bea45cddSEd Schouten state = "runnable"; 305bea45cddSEd Schouten else if (TD_IS_SLEEPING(td)) { 306bea45cddSEd Schouten /* XXX: If we're sleeping, are we ever not in a queue? */ 307bea45cddSEd Schouten if (TD_ON_SLEEPQ(td)) 308bea45cddSEd Schouten state = td->td_wmesg; 309bea45cddSEd Schouten else 310bea45cddSEd Schouten state = "sleeping without queue"; 311bea45cddSEd Schouten } else if (TD_ON_LOCK(td)) { 312bea45cddSEd Schouten state = td->td_lockname; 313bea45cddSEd Schouten stateprefix = "*"; 314bea45cddSEd Schouten } else if (TD_IS_SUSPENDED(td)) 315bea45cddSEd Schouten state = "suspended"; 316bea45cddSEd Schouten else if (TD_AWAITING_INTR(td)) 317bea45cddSEd Schouten state = "intrwait"; 318dd970f41SEd Schouten else if (p->p_state == PRS_ZOMBIE) 319ad765b09SRobert Watson state = "zombie"; 320bea45cddSEd Schouten else 321bea45cddSEd Schouten state = "unknown"; 322bea45cddSEd Schouten pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT; 323bea45cddSEd Schouten thread_unlock(td); 324dd970f41SEd Schouten if (p->p_state == PRS_NEW || p->p_state == PRS_ZOMBIE) 325bea45cddSEd Schouten rss = 0; 326bea45cddSEd Schouten else 327dd970f41SEd Schouten rss = pgtok(vmspace_resident_count(p->p_vmspace)); 328dd970f41SEd Schouten microuptime(&rtime); 329dd970f41SEd Schouten timevalsub(&rtime, &p->p_stats->p_start); 330dd970f41SEd Schouten rufetchcalc(p, &ru, &utime, &stime); 331dd970f41SEd Schouten pid = p->p_pid; 332dd970f41SEd Schouten strlcpy(comm, p->p_comm, sizeof comm); 333dd970f41SEd Schouten PROC_UNLOCK(p); 334bea45cddSEd Schouten 335dd970f41SEd Schouten /* Print command, pid, state, rtime, utime, stime, %cpu, and rss. */ 336*6858c2ccSConrad Meyer sbuf_printf(&sb, 337dd970f41SEd Schouten " cmd: %s %d [%s%s] %ld.%02ldr %ld.%02ldu %ld.%02lds %d%% %ldk\n", 338bea45cddSEd Schouten comm, pid, stateprefix, state, 339dd970f41SEd Schouten (long)rtime.tv_sec, rtime.tv_usec / 10000, 340bea45cddSEd Schouten (long)utime.tv_sec, utime.tv_usec / 10000, 341bea45cddSEd Schouten (long)stime.tv_sec, stime.tv_usec / 10000, 342bea45cddSEd Schouten pctcpu / 100, rss); 343*6858c2ccSConrad Meyer 344*6858c2ccSConrad Meyer out: 345*6858c2ccSConrad Meyer sbuf_finish(&sb); 346*6858c2ccSConrad Meyer sbuf_delete(&sb); 347bea45cddSEd Schouten } 348