1204076Spjd/*- 2204076Spjd * Copyright (c) 1982, 1986, 1990, 1991, 1993 3219887Spjd * The Regents of the University of California. All rights reserved. 4204076Spjd * (c) UNIX System Laboratories, Inc. 5204076Spjd * All or some portions of this file are derived from material licensed 6204076Spjd * to the University of California by American Telephone and Telegraph 7204076Spjd * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8204076Spjd * the permission of UNIX System Laboratories, Inc. 9204076Spjd * 10204076Spjd * Copyright (c) 2002 Networks Associates Technologies, Inc. 11204076Spjd * All rights reserved. 12204076Spjd * 13204076Spjd * Portions of this software were developed for the FreeBSD Project by 14204076Spjd * ThinkSec AS and NAI Labs, the Security Research Division of Network 15204076Spjd * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 16204076Spjd * ("CBOSS"), as part of the DARPA CHATS research program. 17204076Spjd * 18204076Spjd * Redistribution and use in source and binary forms, with or without 19204076Spjd * modification, are permitted provided that the following conditions 20204076Spjd * are met: 21204076Spjd * 1. Redistributions of source code must retain the above copyright 22204076Spjd * notice, this list of conditions and the following disclaimer. 23204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 24204076Spjd * notice, this list of conditions and the following disclaimer in the 25204076Spjd * documentation and/or other materials provided with the distribution. 26204076Spjd * 4. Neither the name of the University nor the names of its contributors 27204076Spjd * may be used to endorse or promote products derived from this software 28204076Spjd * without specific prior written permission. 29204076Spjd * 30204076Spjd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34221899Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37221899Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39248297Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40263234Srwatson * SUCH DAMAGE. 41248297Spjd */ 42248297Spjd 43204076Spjd#include <sys/cdefs.h> 44204076Spjd__FBSDID("$FreeBSD: releng/11.0/sys/kern/tty_info.c 231095 2012-02-06 18:15:46Z ed $"); 45204076Spjd 46218048Spjd#include <sys/param.h> 47219815Spjd#include <sys/lock.h> 48219847Spjd#include <sys/mutex.h> 49219815Spjd#include <sys/proc.h> 50219815Spjd#include <sys/resourcevar.h> 51218048Spjd#include <sys/sched.h> 52204076Spjd#include <sys/systm.h> 53204076Spjd#include <sys/tty.h> 54204076Spjd 55204076Spjd#include <vm/vm.h> 56204076Spjd#include <vm/pmap.h> 57204076Spjd#include <vm/vm_map.h> 58204076Spjd 59219815Spjd/* 60219815Spjd * Returns 1 if p2 is "better" than p1 61219815Spjd * 62219815Spjd * The algorithm for picking the "interesting" process is thus: 63219815Spjd * 64219815Spjd * 1) Only foreground processes are eligible - implied. 65219815Spjd * 2) Runnable processes are favored over anything else. The runner 66219815Spjd * with the highest cpu utilization is picked (p_estcpu). Ties are 67219815Spjd * broken by picking the highest pid. 68219815Spjd * 3) The sleeper with the shortest sleep time is next. With ties, 69219815Spjd * we pick out just "short-term" sleepers (P_SINTR == 0). 70219815Spjd * 4) Further ties are broken by picking the highest pid. 71219815Spjd */ 72219815Spjd 73219815Spjd#define TESTAB(a, b) ((a)<<1 | (b)) 74219815Spjd#define ONLYA 2 75219815Spjd#define ONLYB 1 76219815Spjd#define BOTH 3 77219815Spjd 78219815Spjdstatic int 79219815Spjdproc_sum(struct proc *p, fixpt_t *estcpup) 80204076Spjd{ 81204076Spjd struct thread *td; 82204076Spjd int estcpu; 83204076Spjd int val; 84218138Spjd 85218138Spjd val = 0; 86204076Spjd estcpu = 0; 87204076Spjd FOREACH_THREAD_IN_PROC(p, td) { 88204076Spjd thread_lock(td); 89204076Spjd if (TD_ON_RUNQ(td) || 90229945Spjd TD_IS_RUNNING(td)) 91225781Spjd val = 1; 92225781Spjd estcpu += sched_pctcpu(td); 93204076Spjd thread_unlock(td); 94204076Spjd } 95204076Spjd *estcpup = estcpu; 96229945Spjd 97225781Spjd return (val); 98204076Spjd} 99204076Spjd 100204076Spjdstatic int 101204076Spjdthread_compare(struct thread *td, struct thread *td2) 102204076Spjd{ 103204076Spjd int runa, runb; 104204076Spjd int slpa, slpb; 105229945Spjd fixpt_t esta, estb; 106225781Spjd 107204076Spjd if (td == NULL) 108225781Spjd return (1); 109204076Spjd 110204076Spjd /* 111204076Spjd * Fetch running stats, pctcpu usage, and interruptable flag. 112229945Spjd */ 113225781Spjd thread_lock(td); 114204076Spjd runa = TD_IS_RUNNING(td) | TD_ON_RUNQ(td); 115225781Spjd slpa = td->td_flags & TDF_SINTR; 116204076Spjd esta = sched_pctcpu(td); 117204076Spjd thread_unlock(td); 118204076Spjd thread_lock(td2); 119204076Spjd runb = TD_IS_RUNNING(td2) | TD_ON_RUNQ(td2); 120204076Spjd estb = sched_pctcpu(td2); 121204076Spjd slpb = td2->td_flags & TDF_SINTR; 122204076Spjd thread_unlock(td2); 123204076Spjd /* 124204076Spjd * see if at least one of them is runnable 125204076Spjd */ 126204076Spjd switch (TESTAB(runa, runb)) { 127204076Spjd case ONLYA: 128204076Spjd return (0); 129204076Spjd case ONLYB: 130204076Spjd return (1); 131204076Spjd case BOTH: 132204076Spjd break; 133204076Spjd } 134204076Spjd /* 135204076Spjd * favor one with highest recent cpu utilization 136204076Spjd */ 137204076Spjd if (estb > esta) 138204076Spjd return (1); 139204076Spjd if (esta > estb) 140204076Spjd return (0); 141219864Spjd /* 142219864Spjd * favor one sleeping in a non-interruptible sleep 143204076Spjd */ 144219864Spjd switch (TESTAB(slpa, slpb)) { 145204076Spjd case ONLYA: 146219864Spjd return (0); 147204076Spjd case ONLYB: 148204076Spjd return (1); 149204076Spjd case BOTH: 150204076Spjd break; 151218048Spjd } 152218048Spjd 153229699Spjd return (td < td2); 154218048Spjd} 155221899Spjd 156221899Spjdstatic int 157218048Spjdproc_compare(struct proc *p1, struct proc *p2) 158218048Spjd{ 159218048Spjd 160218048Spjd int runa, runb; 161221899Spjd fixpt_t esta, estb; 162218048Spjd 163218048Spjd if (p1 == NULL) 164218048Spjd return (1); 165218048Spjd 166218048Spjd /* 167218048Spjd * Fetch various stats about these processes. After we drop the 168218048Spjd * lock the information could be stale but the race is unimportant. 169218048Spjd */ 170218048Spjd PROC_LOCK(p1); 171218048Spjd runa = proc_sum(p1, &esta); 172225781Spjd PROC_UNLOCK(p1); 173225781Spjd PROC_LOCK(p2); 174218048Spjd runb = proc_sum(p2, &estb); 175218048Spjd PROC_UNLOCK(p2); 176218048Spjd 177218048Spjd /* 178218048Spjd * see if at least one of them is runnable 179218048Spjd */ 180218048Spjd switch (TESTAB(runa, runb)) { 181221899Spjd case ONLYA: 182221899Spjd return (0); 183221899Spjd case ONLYB: 184221899Spjd return (1); 185221899Spjd case BOTH: 186221899Spjd break; 187221899Spjd } 188221899Spjd /* 189221899Spjd * favor one with highest recent cpu utilization 190218048Spjd */ 191221899Spjd if (estb > esta) 192221899Spjd return (1); 193221899Spjd if (esta > estb) 194221899Spjd return (0); 195221899Spjd /* 196221899Spjd * weed out zombies 197221899Spjd */ 198221899Spjd switch (TESTAB(p1->p_state == PRS_ZOMBIE, p2->p_state == PRS_ZOMBIE)) { 199221899Spjd case ONLYA: 200221899Spjd return (1); 201221899Spjd case ONLYB: 202221899Spjd return (0); 203221899Spjd case BOTH: 204225781Spjd break; 205221899Spjd } 206225781Spjd 207221899Spjd return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 208221899Spjd} 209221899Spjd 210218048Spjd/* 211218048Spjd * Report on state of foreground process group. 212218048Spjd */ 213225781Spjdvoid 214225781Spjdtty_info(struct tty *tp) 215218048Spjd{ 216218048Spjd struct timeval rtime, utime, stime; 217218048Spjd struct proc *p, *ppick; 218225781Spjd struct thread *td, *tdpick; 219225781Spjd const char *stateprefix, *state; 220218048Spjd long rss; 221218048Spjd int load, pctcpu; 222218048Spjd pid_t pid; 223225781Spjd char comm[MAXCOMLEN + 1]; 224225781Spjd struct rusage ru; 225218048Spjd 226218048Spjd tty_lock_assert(tp, MA_OWNED); 227218048Spjd 228223585Spjd if (tty_checkoutq(tp) == 0) 229248297Spjd return; 230248297Spjd 231248297Spjd /* Print load average. */ 232248297Spjd load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 233248297Spjd ttyprintf(tp, "%sload: %d.%02d ", tp->t_column == 0 ? "" : "\n", 234255219Spjd load / 100, load % 100); 235248297Spjd 236248297Spjd if (tp->t_session == NULL) { 237248297Spjd ttyprintf(tp, "not a controlling terminal\n"); 238248297Spjd return; 239248297Spjd } 240248297Spjd if (tp->t_pgrp == NULL) { 241248297Spjd ttyprintf(tp, "no foreground process group\n"); 242248297Spjd return; 243255219Spjd } 244255219Spjd PGRP_LOCK(tp->t_pgrp); 245255219Spjd if (LIST_EMPTY(&tp->t_pgrp->pg_members)) { 246248297Spjd PGRP_UNLOCK(tp->t_pgrp); 247248297Spjd ttyprintf(tp, "empty foreground process group\n"); 248223584Spjd return; 249248297Spjd } 250298317Saraujo 251248297Spjd /* 252248297Spjd * Pick the most interesting process and copy some of its 253248297Spjd * state for printing later. This operation could rely on stale 254248297Spjd * data as we can't hold the proc slock or thread locks over the 255248297Spjd * whole list. However, we're guaranteed not to reference an exited 256248297Spjd * thread or proc since we hold the tty locked. 257248297Spjd */ 258248297Spjd p = NULL; 259248297Spjd LIST_FOREACH(ppick, &tp->t_pgrp->pg_members, p_pglist) 260248297Spjd if (proc_compare(p, ppick)) 261248297Spjd p = ppick; 262248297Spjd 263255219Spjd PROC_LOCK(p); 264255219Spjd PGRP_UNLOCK(tp->t_pgrp); 265248297Spjd td = NULL; 266248297Spjd FOREACH_THREAD_IN_PROC(p, tdpick) 267248297Spjd if (thread_compare(td, tdpick)) 268248297Spjd td = tdpick; 269298317Saraujo stateprefix = ""; 270248297Spjd thread_lock(td); 271248297Spjd if (TD_IS_RUNNING(td)) 272248297Spjd state = "running"; 273248297Spjd else if (TD_ON_RUNQ(td) || TD_CAN_RUN(td)) 274248297Spjd state = "runnable"; 275248297Spjd else if (TD_IS_SLEEPING(td)) { 276248297Spjd /* XXX: If we're sleeping, are we ever not in a queue? */ 277223585Spjd if (TD_ON_SLEEPQ(td)) 278221898Spjd state = td->td_wmesg; 279218048Spjd else 280218048Spjd state = "sleeping without queue"; 281218048Spjd } else if (TD_ON_LOCK(td)) { 282218048Spjd state = td->td_lockname; 283218048Spjd stateprefix = "*"; 284218048Spjd } else if (TD_IS_SUSPENDED(td)) 285218048Spjd state = "suspended"; 286218048Spjd else if (TD_AWAITING_INTR(td)) 287218048Spjd state = "intrwait"; 288218048Spjd else if (p->p_state == PRS_ZOMBIE) 289218048Spjd state = "zombie"; 290218048Spjd else 291218048Spjd state = "unknown"; 292218048Spjd pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT; 293218048Spjd thread_unlock(td); 294219847Spjd if (p->p_state == PRS_NEW || p->p_state == PRS_ZOMBIE) 295221899Spjd rss = 0; 296221899Spjd else 297219847Spjd rss = pgtok(vmspace_resident_count(p->p_vmspace)); 298218048Spjd microuptime(&rtime); 299218048Spjd timevalsub(&rtime, &p->p_stats->p_start); 300 rufetchcalc(p, &ru, &utime, &stime); 301 pid = p->p_pid; 302 strlcpy(comm, p->p_comm, sizeof comm); 303 PROC_UNLOCK(p); 304 305 /* Print command, pid, state, rtime, utime, stime, %cpu, and rss. */ 306 ttyprintf(tp, 307 " cmd: %s %d [%s%s] %ld.%02ldr %ld.%02ldu %ld.%02lds %d%% %ldk\n", 308 comm, pid, stateprefix, state, 309 (long)rtime.tv_sec, rtime.tv_usec / 10000, 310 (long)utime.tv_sec, utime.tv_usec / 10000, 311 (long)stime.tv_sec, stime.tv_usec / 10000, 312 pctcpu / 100, rss); 313} 314