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