From owner-svn-src-head@freebsd.org Mon Sep 5 08:27:05 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EDC37A9D3A7; Mon, 5 Sep 2016 08:27:05 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C932879C; Mon, 5 Sep 2016 08:27:05 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u858R5x4085596; Mon, 5 Sep 2016 08:27:05 GMT (envelope-from des@FreeBSD.org) Received: (from des@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u858R4bu085591; Mon, 5 Sep 2016 08:27:04 GMT (envelope-from des@FreeBSD.org) Message-Id: <201609050827.u858R4bu085591@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: des set sender to des@FreeBSD.org using -f From: =?UTF-8?Q?Dag-Erling_Sm=c3=b8rgrav?= Date: Mon, 5 Sep 2016 08:27:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305414 - in head: contrib/top usr.bin/top X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Sep 2016 08:27:06 -0000 Author: des Date: Mon Sep 5 08:27:04 2016 New Revision: 305414 URL: https://svnweb.freebsd.org/changeset/base/305414 Log: Add a toggle to display the approximate amount of swap used by each process. We don't *quite* pull that number out of our backside, as the actual number is difficult to determine without modifying the VM system to report it, but it's still useful to get an idea of what's going on when a machine unexpectedly starts swapping. MFC after: 1 week Modified: head/contrib/top/commands.c head/contrib/top/machine.h head/contrib/top/top.c head/contrib/top/top.xs head/usr.bin/top/machine.c Modified: head/contrib/top/commands.c ============================================================================== --- head/contrib/top/commands.c Mon Sep 5 06:46:04 2016 (r305413) +++ head/contrib/top/commands.c Mon Sep 5 08:27:04 2016 (r305414) @@ -104,6 +104,7 @@ S - toggle the displaying of syste a - toggle the displaying of process titles\n\ t - toggle the display of this process\n\ u - display processes for only one user (+ selects all users)\n\ +w - toggle the display of swap use for each process\n\ z - toggle the displaying of the system idle process\n\ \n\ \n", stdout); Modified: head/contrib/top/machine.h ============================================================================== --- head/contrib/top/machine.h Mon Sep 5 06:46:04 2016 (r305413) +++ head/contrib/top/machine.h Mon Sep 5 08:27:04 2016 (r305414) @@ -72,6 +72,7 @@ struct process_select int wcpu; /* show weighted cpu */ int jid; /* only this jid (unless jid == -1) */ int jail; /* show jail ID */ + int swap; /* show swap usage */ int kidle; /* show per-CPU idle threads */ char *command; /* only this command (unless == NULL) */ }; @@ -82,8 +83,8 @@ char *format_header(); char *format_next_process(); void toggle_pcpustats(void); void get_system_info(struct system_info *si); -int machine_init(struct statics *statics, char do_unames); -int proc_owner(int pid); +int machine_init(struct statics *statics, char do_unames); +int proc_owner(int pid); /* non-int routines typically used by the machine dependent module */ char *printable(); Modified: head/contrib/top/top.c ============================================================================== --- head/contrib/top/top.c Mon Sep 5 06:46:04 2016 (r305413) +++ head/contrib/top/top.c Mon Sep 5 08:27:04 2016 (r305414) @@ -188,9 +188,9 @@ char *argv[]; fd_set readfds; #ifdef ORDER - static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJo"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJwo"; #else - static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJ"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJw"; #endif /* these defines enumerate the "strchr"s of the commands in command_chars */ #define CMD_redraw 0 @@ -219,8 +219,9 @@ char *argv[]; #define CMD_kidletog 22 #define CMD_pcputog 23 #define CMD_jail 24 +#define CMD_swaptog 25 #ifdef ORDER -#define CMD_order 25 +#define CMD_order 26 #endif /* set the buffer for stdout */ @@ -254,6 +255,7 @@ char *argv[]; ps.wcpu = 1; ps.jid = -1; ps.jail = No; + ps.swap = No; ps.kidle = Yes; ps.command = NULL; @@ -280,7 +282,7 @@ char *argv[]; optind = 1; } - while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:t")) != EOF) + while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:tw")) != EOF) { switch(i) { @@ -418,6 +420,10 @@ char *argv[]; pcpu_stats = !pcpu_stats; break; + case 'w': + ps.swap = 1; + break; + case 'z': ps.kidle = !ps.kidle; break; @@ -1141,6 +1147,15 @@ restart: reset_display(); putchar('\r'); break; + case CMD_swaptog: + ps.swap = !ps.swap; + new_message(MT_standout | MT_delayed, + " %sisplaying per-process swap usage.", + ps.swap ? "D" : "Not d"); + header_text = format_header(uname_field); + reset_display(); + putchar('\r'); + break; default: new_message(MT_standout, " BAD CASE IN SWITCH!"); putchar('\r'); Modified: head/contrib/top/top.xs ============================================================================== --- head/contrib/top/top.xs Mon Sep 5 06:46:04 2016 (r305413) +++ head/contrib/top/top.xs Mon Sep 5 08:27:04 2016 (r305414) @@ -10,7 +10,7 @@ top \- display and update information ab .SH SYNOPSIS .B top [ -.B \-abCHIijnPqStuvz +.B \-abCHIijnPqStuvwz ] [ .BI \-d count ] [ @@ -148,6 +148,9 @@ Write version number information to stde No other processing takes place when this option is used. To see current revision information while top is running, use the help command \*(lq?\*(rq. .TP +.B \-w +Display approximate swap usage for each process. +.TP .B \-z Do not display the system idle process. .TP @@ -167,11 +170,12 @@ Set the delay between screen updates to seconds. The default delay between updates is \nD seconds. .TP .BI \-o field -Sort the process display area on the specified field. The field name is -the name of the column as seen in the output, but in lower case. Likely -values are \*(lqcpu\*(rq, \*(lqsize\*(rq, \*(lqres\*(rq, and \*(lqtime\*(rq, -but may vary on different operating systems. Note that -not all operating systems support this option. +Sort the process display area on the specified field. The field name +is the name of the column as seen in the output, but in lower case: +\*(lqcpu\*(lq, \*(rqsize\*(lq, \*(rqres\*(lq, \*(rqtime\*(lq, +\*(rqpri\*(lq, \*(rqthreads\*(lq, \*(lqtotal\*(lq, \*(rqread\*(lq, +\*(rqwrite\*(lq, \*(rqfault\*(lq, \*(rqvcsw\*(lq, \*(rqivcsw\*(lq, +\*(lqjid\*(lq, \*(rqswap\*(lq or \*(rqpid\*(lq. .TP .BI \-J jail Show only those processes owned by @@ -226,6 +230,7 @@ The options .BR \-S , .BR \-t , .BR \-u , +.BR \-w , and .B \-z are actually toggles. A second specification of any of these options @@ -346,6 +351,9 @@ Toggle the display of the .I top process. .TP +.B w +Toggle the display of swap usage. +.TP .B z Toggle the display of the system idle process. .SH "THE DISPLAY" @@ -379,8 +387,9 @@ is specified, a UID column will be subst PRI is the current priority of the process, NICE is the nice amount (in the range \-20 to 20), SIZE is the total size of the process (text, data, and stack), -RES is the current amount of resident memory (both SIZE and RES are -given in kilobytes), +RES is the current amount of resident memory, +SWAP is the approximate amount of swap, if enabled +(SIZE, RES and SWAP are given in kilobytes), STATE is the current state (one of \*(lqSTART\*(rq, \*(lqRUN\*(rq (shown as \*(lqCPUn\*(rq on SMP systems), \*(lqSLEEP\*(rq, \*(lqSTOP\*(rq, \*(lqZOMB\*(rq, \*(lqWAIT\*(rq, \*(lqLOCK\*(rq or the event on which the Modified: head/usr.bin/top/machine.c ============================================================================== --- head/usr.bin/top/machine.c Mon Sep 5 06:46:04 2016 (r305413) +++ head/usr.bin/top/machine.c Mon Sep 5 08:27:04 2016 (r305414) @@ -69,7 +69,9 @@ static int namelength = 8; #endif /* TOP_JID_LEN based on max of 999999 */ #define TOP_JID_LEN 7 +#define TOP_SWAP_LEN 6 static int jidlength; +static int swaplength; static int cmdlengthdelta; /* Prototypes for top internals */ @@ -111,20 +113,20 @@ static char io_header[] = "%5d%*s %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s" static char smp_header_thr[] = - " PID%*s %-*.*s THR PRI NICE SIZE RES STATE C TIME %7s COMMAND"; + " PID%*s %-*.*s THR PRI NICE SIZE RES%*s STATE C TIME %7s COMMAND"; static char smp_header[] = - " PID%*s %-*.*s " "PRI NICE SIZE RES STATE C TIME %7s COMMAND"; + " PID%*s %-*.*s " "PRI NICE SIZE RES%*s STATE C TIME %7s COMMAND"; #define smp_Proc_format \ - "%5d%*s %-*.*s %s%3d %4s%7s %6s %-6.6s %2d%7s %6.2f%% %.*s" + "%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s %2d%7s %6.2f%% %.*s" static char up_header_thr[] = - " PID%*s %-*.*s THR PRI NICE SIZE RES STATE TIME %7s COMMAND"; + " PID%*s %-*.*s THR PRI NICE SIZE RES%*s STATE TIME %7s COMMAND"; static char up_header[] = - " PID%*s %-*.*s " "PRI NICE SIZE RES STATE TIME %7s COMMAND"; + " PID%*s %-*.*s " "PRI NICE SIZE RES%*s STATE TIME %7s COMMAND"; #define up_Proc_format \ - "%5d%*s %-*.*s %s%3d %4s%7s %6s %-6.6s%.0d%7s %6.2f%% %.*s" + "%5d%*s %-*.*s %s%3d %4s%7s %6s%*.*s %-6.6s%.0d%7s %6.2f%% %.*s" /* process state names for the "STATE" column of the display */ @@ -227,6 +229,10 @@ static int pageshift; /* log base 2 of #define pagetok(size) ((size) << pageshift) +/* swap usage */ +#define ki_swap(kip) \ + ((kip)->ki_swrss > (kip)->ki_rssize ? (kip)->ki_swrss - (kip)->ki_rssize : 0) + /* useful externals */ long percentages(); @@ -237,7 +243,7 @@ long percentages(); char *ordernames[] = { "cpu", "size", "res", "time", "pri", "threads", "total", "read", "write", "fault", "vcsw", "ivcsw", - "jid", "pid", NULL + "jid", "swap", "pid", NULL }; #endif @@ -252,6 +258,7 @@ static long *pcpu_cp_old; static long *pcpu_cp_diff; static int *pcpu_cpu_states; +static int compare_swap(const void *a, const void *b); static int compare_jid(const void *a, const void *b); static int compare_pid(const void *a, const void *b); static int compare_tid(const void *a, const void *b); @@ -412,6 +419,11 @@ format_header(char *uname_field) else jidlength = 0; + if (ps.swap) + swaplength = TOP_SWAP_LEN + 1; /* +1 for extra left space */ + else + swaplength = 0; + switch (displaymode) { case DISP_CPU: /* @@ -426,6 +438,7 @@ format_header(char *uname_field) snprintf(Header, sizeof(Header), prehead, jidlength, ps.jail ? " JID" : "", namelength, namelength, uname_field, + swaplength, ps.swap ? " SWAP" : "", ps.wcpu ? "WCPU" : "CPU"); break; case DISP_IO: @@ -902,7 +915,8 @@ format_next_process(caddr_t handle, char int cpu, state; struct rusage ru, *rup; long p_tot, s_tot; - char *proc_fmt, thr_buf[6], jid_buf[TOP_JID_LEN + 1]; + char *proc_fmt, thr_buf[6]; + char jid_buf[TOP_JID_LEN + 1], swap_buf[TOP_SWAP_LEN + 1]; char *cmdbuf = NULL; char **args; const int cmdlen = 128; @@ -1061,6 +1075,13 @@ format_next_process(caddr_t handle, char snprintf(jid_buf, sizeof(jid_buf), "%*d", jidlength - 1, pp->ki_jid); + if (ps.swap == 0) + swap_buf[0] = '\0'; + else + snprintf(swap_buf, sizeof(swap_buf), "%*s", + swaplength - 1, + format_k2(pagetok(ki_swap(pp)))); /* XXX */ + if (displaymode == DISP_IO) { oldp = get_old_proc(pp); if (oldp != NULL) { @@ -1122,6 +1143,7 @@ format_next_process(caddr_t handle, char format_nice(pp), format_k2(PROCSIZE(pp)), format_k2(pagetok(pp->ki_rssize)), + swaplength, swaplength, swap_buf, status, cpu, format_time(cputime), @@ -1309,6 +1331,12 @@ static int sorted_state[] = { return (diff > 0 ? 1 : -1); \ } while (0) +#define ORDERKEY_SWAP(a, b) do { \ + int diff = (int)ki_swap(b) - (int)ki_swap(a); \ + if (diff != 0) \ + return (diff > 0 ? 1 : -1); \ +} while (0) + /* compare_cpu - the comparison function for sorting by cpu percentage */ int @@ -1357,6 +1385,7 @@ int (*compares[])() = { compare_vcsw, compare_ivcsw, compare_jid, + compare_swap, NULL }; @@ -1467,6 +1496,24 @@ compare_jid(const void *arg1, const void return (0); } + +/* compare_swap - the comparison function for sorting by swap */ +static int +compare_swap(const void *arg1, const void *arg2) +{ + struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; + struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; + + ORDERKEY_SWAP(p1, p2); + ORDERKEY_PCTCPU(p1, p2); + ORDERKEY_CPTICKS(p1, p2); + ORDERKEY_STATE(p1, p2); + ORDERKEY_PRIO(p1, p2); + ORDERKEY_RSSIZE(p1, p2); + ORDERKEY_MEM(p1, p2); + + return (0); +} #endif /* ORDER */ /* assorted comparison functions for sorting by i/o */