17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5154eb83fSjwadams  * Common Development and Distribution License (the "License").
6154eb83fSjwadams  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
220605fe78SGordon Ross  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23d7025c85SJonathan Adams  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24c3377ee9SJohn Levon  * Copyright 2019 Joyent, Inc.
252a12f85aSJeremy Jones  * Copyright (c) 2013 by Delphix. All rights reserved.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <mdb/mdb_param.h>
297c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
307c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
317c478bd9Sstevel@tonic-gate #include <mdb/mdb_ctf.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <sys/thread.h>
357c478bd9Sstevel@tonic-gate #include <sys/session.h>
367c478bd9Sstevel@tonic-gate #include <sys/user.h>
377c478bd9Sstevel@tonic-gate #include <sys/proc.h>
387c478bd9Sstevel@tonic-gate #include <sys/var.h>
397c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
407c478bd9Sstevel@tonic-gate #include <sys/callo.h>
417c478bd9Sstevel@tonic-gate #include <sys/priocntl.h>
427c478bd9Sstevel@tonic-gate #include <sys/class.h>
437c478bd9Sstevel@tonic-gate #include <sys/regset.h>
447c478bd9Sstevel@tonic-gate #include <sys/stack.h>
457c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
467c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
477c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
487c478bd9Sstevel@tonic-gate #include <sys/flock_impl.h>
497c478bd9Sstevel@tonic-gate #include <sys/kmem_impl.h>
507c478bd9Sstevel@tonic-gate #include <sys/vmem_impl.h>
517c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
527c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
537c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h>
547c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
557c478bd9Sstevel@tonic-gate #include <sys/sysconf.h>
567c478bd9Sstevel@tonic-gate #include <sys/task.h>
577c478bd9Sstevel@tonic-gate #include <sys/project.h>
587c478bd9Sstevel@tonic-gate #include <sys/errorq_impl.h>
597c478bd9Sstevel@tonic-gate #include <sys/cred_impl.h>
607c478bd9Sstevel@tonic-gate #include <sys/zone.h>
617c478bd9Sstevel@tonic-gate #include <sys/panic.h>
627c478bd9Sstevel@tonic-gate #include <regex.h>
637c478bd9Sstevel@tonic-gate #include <sys/port_impl.h>
6471a582fbSJohn Levon #include <sys/contract/process_impl.h>
657c478bd9Sstevel@tonic-gate 
66fa9e4066Sahrens #include "avl.h"
674c06356bSdh #include "bio.h"
684c06356bSdh #include "bitset.h"
69b5fca8f8Stomee #include "combined.h"
707c478bd9Sstevel@tonic-gate #include "contract.h"
717c478bd9Sstevel@tonic-gate #include "cpupart_mdb.h"
720605fe78SGordon Ross #include "cred.h"
734c06356bSdh #include "ctxop.h"
744c06356bSdh #include "cyclic.h"
754c06356bSdh #include "damap.h"
76a288e5a9SJoshua M. Clulow #include "ddi_periodic.h"
777c478bd9Sstevel@tonic-gate #include "devinfo.h"
7839f030b8SPatrick Mooney #include "dnlc.h"
794c06356bSdh #include "findstack.h"
804c06356bSdh #include "fm.h"
812a12f85aSJeremy Jones #include "gcore.h"
824c06356bSdh #include "group.h"
835febcb4aSScott Carter, SD IOSW #include "irm.h"
844c06356bSdh #include "kgrep.h"
854c06356bSdh #include "kmem.h"
864c06356bSdh #include "ldi.h"
877c478bd9Sstevel@tonic-gate #include "leaky.h"
887c478bd9Sstevel@tonic-gate #include "lgrp.h"
897c478bd9Sstevel@tonic-gate #include "list.h"
907c478bd9Sstevel@tonic-gate #include "log.h"
914c06356bSdh #include "mdi.h"
924c06356bSdh #include "memory.h"
937c478bd9Sstevel@tonic-gate #include "mmd.h"
944c06356bSdh #include "modhash.h"
954c06356bSdh #include "ndievents.h"
967c478bd9Sstevel@tonic-gate #include "net.h"
97f4b3ec61Sdh #include "netstack.h"
987c478bd9Sstevel@tonic-gate #include "nvpair.h"
99e386d4ddSRobert Mustacchi #include "pci.h"
1004c06356bSdh #include "pg.h"
1014c06356bSdh #include "rctl.h"
1027c478bd9Sstevel@tonic-gate #include "sobj.h"
1034c06356bSdh #include "streams.h"
1047c478bd9Sstevel@tonic-gate #include "sysevent.h"
105e0ad97e3SJonathan Adams #include "taskq.h"
1064c06356bSdh #include "thread.h"
1074c06356bSdh #include "tsd.h"
10845916cd2Sjpk #include "tsol.h"
1097c478bd9Sstevel@tonic-gate #include "typegraph.h"
1107c478bd9Sstevel@tonic-gate #include "vfs.h"
1117c478bd9Sstevel@tonic-gate #include "zone.h"
11226947304SEvan Yan #include "hotplug.h"
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate /*
1157c478bd9Sstevel@tonic-gate  * Surely this is defined somewhere...
1167c478bd9Sstevel@tonic-gate  */
1177c478bd9Sstevel@tonic-gate #define	NINTR		16
1187c478bd9Sstevel@tonic-gate 
119bb8b5132Sek #define	KILOS		10
120bb8b5132Sek #define	MEGS		20
121bb8b5132Sek #define	GIGS		30
122bb8b5132Sek 
1237c478bd9Sstevel@tonic-gate #ifndef STACK_BIAS
1247c478bd9Sstevel@tonic-gate #define	STACK_BIAS	0
1257c478bd9Sstevel@tonic-gate #endif
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate static char
pstat2ch(uchar_t state)1287c478bd9Sstevel@tonic-gate pstat2ch(uchar_t state)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate 	switch (state) {
1317c478bd9Sstevel@tonic-gate 		case SSLEEP: return ('S');
1327c478bd9Sstevel@tonic-gate 		case SRUN: return ('R');
1337c478bd9Sstevel@tonic-gate 		case SZOMB: return ('Z');
1347c478bd9Sstevel@tonic-gate 		case SIDL: return ('I');
1357c478bd9Sstevel@tonic-gate 		case SONPROC: return ('O');
1367c478bd9Sstevel@tonic-gate 		case SSTOP: return ('T');
137c97ad5cdSakolb 		case SWAIT: return ('W');
1387c478bd9Sstevel@tonic-gate 		default: return ('?');
1397c478bd9Sstevel@tonic-gate 	}
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate #define	PS_PRTTHREADS	0x1
1437c478bd9Sstevel@tonic-gate #define	PS_PRTLWPS	0x2
1447c478bd9Sstevel@tonic-gate #define	PS_PSARGS	0x4
1457c478bd9Sstevel@tonic-gate #define	PS_TASKS	0x8
1467c478bd9Sstevel@tonic-gate #define	PS_PROJECTS	0x10
1477c478bd9Sstevel@tonic-gate #define	PS_ZONES	0x20
14871a582fbSJohn Levon #define	PS_SERVICES	0x40
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate static int
ps_threadprint(uintptr_t addr,const void * data,void * private)1517c478bd9Sstevel@tonic-gate ps_threadprint(uintptr_t addr, const void *data, void *private)
1527c478bd9Sstevel@tonic-gate {
1537c478bd9Sstevel@tonic-gate 	const kthread_t *t = (const kthread_t *)data;
1547c478bd9Sstevel@tonic-gate 	uint_t prt_flags = *((uint_t *)private);
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	static const mdb_bitmask_t t_state_bits[] = {
1577c478bd9Sstevel@tonic-gate 		{ "TS_FREE",	UINT_MAX,	TS_FREE		},
1587c478bd9Sstevel@tonic-gate 		{ "TS_SLEEP",	TS_SLEEP,	TS_SLEEP	},
1597c478bd9Sstevel@tonic-gate 		{ "TS_RUN",	TS_RUN,		TS_RUN		},
1607c478bd9Sstevel@tonic-gate 		{ "TS_ONPROC",	TS_ONPROC,	TS_ONPROC	},
1617c478bd9Sstevel@tonic-gate 		{ "TS_ZOMB",	TS_ZOMB,	TS_ZOMB		},
1627c478bd9Sstevel@tonic-gate 		{ "TS_STOPPED",	TS_STOPPED,	TS_STOPPED	},
163c97ad5cdSakolb 		{ "TS_WAIT",	TS_WAIT,	TS_WAIT		},
1647c478bd9Sstevel@tonic-gate 		{ NULL,		0,		0		}
1657c478bd9Sstevel@tonic-gate 	};
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	if (prt_flags & PS_PRTTHREADS)
1687c478bd9Sstevel@tonic-gate 		mdb_printf("\tT  %?a <%b>\n", addr, t->t_state, t_state_bits);
1697c478bd9Sstevel@tonic-gate 
170ab618543SJohn Levon 	if (prt_flags & PS_PRTLWPS) {
171ab618543SJohn Levon 		char desc[128] = "";
172ab618543SJohn Levon 
173ab618543SJohn Levon 		(void) thread_getdesc(addr, B_FALSE, desc, sizeof (desc));
174ab618543SJohn Levon 
175ab618543SJohn Levon 		mdb_printf("\tL  %?a ID: %s\n", t->t_lwp, desc);
176ab618543SJohn Levon 	}
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate 
18175cebdd1SRyan Zezeski typedef struct mdb_pflags_proc {
182ab618543SJohn Levon 	struct pid	*p_pidp;
18375cebdd1SRyan Zezeski 	ushort_t	p_pidflag;
18475cebdd1SRyan Zezeski 	uint_t		p_proc_flag;
18575cebdd1SRyan Zezeski 	uint_t		p_flag;
18675cebdd1SRyan Zezeski } mdb_pflags_proc_t;
18775cebdd1SRyan Zezeski 
1885b91507bSJoshua M. Clulow static int
pflags(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1895b91507bSJoshua M. Clulow pflags(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1905b91507bSJoshua M. Clulow {
19175cebdd1SRyan Zezeski 	mdb_pflags_proc_t pr;
1925b91507bSJoshua M. Clulow 	struct pid pid;
1935b91507bSJoshua M. Clulow 
1945b91507bSJoshua M. Clulow 	static const mdb_bitmask_t p_flag_bits[] = {
1955b91507bSJoshua M. Clulow 		{ "SSYS",		SSYS,		SSYS		},
1965b91507bSJoshua M. Clulow 		{ "SEXITING",		SEXITING,	SEXITING	},
1975b91507bSJoshua M. Clulow 		{ "SITBUSY",		SITBUSY,	SITBUSY		},
1985b91507bSJoshua M. Clulow 		{ "SFORKING",		SFORKING,	SFORKING	},
1995b91507bSJoshua M. Clulow 		{ "SWATCHOK",		SWATCHOK,	SWATCHOK	},
2005b91507bSJoshua M. Clulow 		{ "SKILLED",		SKILLED,	SKILLED		},
2015b91507bSJoshua M. Clulow 		{ "SSCONT",		SSCONT,		SSCONT		},
2025b91507bSJoshua M. Clulow 		{ "SZONETOP",		SZONETOP,	SZONETOP	},
2035b91507bSJoshua M. Clulow 		{ "SEXTKILLED",		SEXTKILLED,	SEXTKILLED	},
2045b91507bSJoshua M. Clulow 		{ "SUGID",		SUGID,		SUGID		},
2055b91507bSJoshua M. Clulow 		{ "SEXECED",		SEXECED,	SEXECED		},
2065b91507bSJoshua M. Clulow 		{ "SJCTL",		SJCTL,		SJCTL		},
2075b91507bSJoshua M. Clulow 		{ "SNOWAIT",		SNOWAIT,	SNOWAIT		},
2085b91507bSJoshua M. Clulow 		{ "SVFORK",		SVFORK,		SVFORK		},
2095b91507bSJoshua M. Clulow 		{ "SVFWAIT",		SVFWAIT,	SVFWAIT		},
2105b91507bSJoshua M. Clulow 		{ "SEXITLWPS",		SEXITLWPS,	SEXITLWPS	},
2115b91507bSJoshua M. Clulow 		{ "SHOLDFORK",		SHOLDFORK,	SHOLDFORK	},
2125b91507bSJoshua M. Clulow 		{ "SHOLDFORK1",		SHOLDFORK1,	SHOLDFORK1	},
2135b91507bSJoshua M. Clulow 		{ "SCOREDUMP",		SCOREDUMP,	SCOREDUMP	},
2145b91507bSJoshua M. Clulow 		{ "SMSACCT",		SMSACCT,	SMSACCT		},
2155b91507bSJoshua M. Clulow 		{ "SLWPWRAP",		SLWPWRAP,	SLWPWRAP	},
2165b91507bSJoshua M. Clulow 		{ "SAUTOLPG",		SAUTOLPG,	SAUTOLPG	},
2175b91507bSJoshua M. Clulow 		{ "SNOCD",		SNOCD,		SNOCD		},
2185b91507bSJoshua M. Clulow 		{ "SHOLDWATCH",		SHOLDWATCH,	SHOLDWATCH	},
2195b91507bSJoshua M. Clulow 		{ "SMSFORK",		SMSFORK,	SMSFORK		},
2205b91507bSJoshua M. Clulow 		{ "SDOCORE",		SDOCORE,	SDOCORE		},
2215b91507bSJoshua M. Clulow 		{ NULL,			0,		0		}
2225b91507bSJoshua M. Clulow 	};
2235b91507bSJoshua M. Clulow 
2245b91507bSJoshua M. Clulow 	static const mdb_bitmask_t p_pidflag_bits[] = {
2255b91507bSJoshua M. Clulow 		{ "CLDPEND",		CLDPEND,	CLDPEND		},
2265b91507bSJoshua M. Clulow 		{ "CLDCONT",		CLDCONT,	CLDCONT		},
2275b91507bSJoshua M. Clulow 		{ "CLDNOSIGCHLD",	CLDNOSIGCHLD,	CLDNOSIGCHLD	},
2285b91507bSJoshua M. Clulow 		{ "CLDWAITPID",		CLDWAITPID,	CLDWAITPID	},
2295b91507bSJoshua M. Clulow 		{ NULL,			0,		0		}
2305b91507bSJoshua M. Clulow 	};
2315b91507bSJoshua M. Clulow 
2325b91507bSJoshua M. Clulow 	static const mdb_bitmask_t p_proc_flag_bits[] = {
2335b91507bSJoshua M. Clulow 		{ "P_PR_TRACE",		P_PR_TRACE,	P_PR_TRACE	},
2345b91507bSJoshua M. Clulow 		{ "P_PR_PTRACE",	P_PR_PTRACE,	P_PR_PTRACE	},
2355b91507bSJoshua M. Clulow 		{ "P_PR_FORK",		P_PR_FORK,	P_PR_FORK	},
2365b91507bSJoshua M. Clulow 		{ "P_PR_LOCK",		P_PR_LOCK,	P_PR_LOCK	},
2375b91507bSJoshua M. Clulow 		{ "P_PR_ASYNC",		P_PR_ASYNC,	P_PR_ASYNC	},
2385b91507bSJoshua M. Clulow 		{ "P_PR_EXEC",		P_PR_EXEC,	P_PR_EXEC	},
2395b91507bSJoshua M. Clulow 		{ "P_PR_BPTADJ",	P_PR_BPTADJ,	P_PR_BPTADJ	},
2405b91507bSJoshua M. Clulow 		{ "P_PR_RUNLCL",	P_PR_RUNLCL,	P_PR_RUNLCL	},
2415b91507bSJoshua M. Clulow 		{ "P_PR_KILLCL",	P_PR_KILLCL,	P_PR_KILLCL	},
2425b91507bSJoshua M. Clulow 		{ NULL,			0,		0		}
2435b91507bSJoshua M. Clulow 	};
2445b91507bSJoshua M. Clulow 
2455b91507bSJoshua M. Clulow 	if (!(flags & DCMD_ADDRSPEC)) {
2465b91507bSJoshua M. Clulow 		if (mdb_walk_dcmd("proc", "pflags", argc, argv) == -1) {
2475b91507bSJoshua M. Clulow 			mdb_warn("can't walk 'proc'");
2485b91507bSJoshua M. Clulow 			return (DCMD_ERR);
2495b91507bSJoshua M. Clulow 		}
2505b91507bSJoshua M. Clulow 		return (DCMD_OK);
2515b91507bSJoshua M. Clulow 	}
2525b91507bSJoshua M. Clulow 
25375cebdd1SRyan Zezeski 	if (mdb_ctf_vread(&pr, "proc_t", "mdb_pflags_proc_t", addr, 0) == -1 ||
2545b91507bSJoshua M. Clulow 	    mdb_vread(&pid, sizeof (pid), (uintptr_t)pr.p_pidp) == -1) {
2555b91507bSJoshua M. Clulow 		mdb_warn("cannot read proc_t or pid");
2565b91507bSJoshua M. Clulow 		return (DCMD_ERR);
2575b91507bSJoshua M. Clulow 	}
2585b91507bSJoshua M. Clulow 
2595b91507bSJoshua M. Clulow 	mdb_printf("%p [pid %d]:\n", addr, pid.pid_id);
2605b91507bSJoshua M. Clulow 	mdb_printf("\tp_flag:      %08x <%b>\n", pr.p_flag, pr.p_flag,
2615b91507bSJoshua M. Clulow 	    p_flag_bits);
2625b91507bSJoshua M. Clulow 	mdb_printf("\tp_pidflag:   %08x <%b>\n", pr.p_pidflag, pr.p_pidflag,
2635b91507bSJoshua M. Clulow 	    p_pidflag_bits);
2645b91507bSJoshua M. Clulow 	mdb_printf("\tp_proc_flag: %08x <%b>\n", pr.p_proc_flag, pr.p_proc_flag,
2655b91507bSJoshua M. Clulow 	    p_proc_flag_bits);
2665b91507bSJoshua M. Clulow 
2675b91507bSJoshua M. Clulow 	return (DCMD_OK);
2685b91507bSJoshua M. Clulow }
2695b91507bSJoshua M. Clulow 
27075cebdd1SRyan Zezeski typedef struct mdb_ps_proc {
27175cebdd1SRyan Zezeski 	char		p_stat;
272ab618543SJohn Levon 	struct pid	*p_pidp;
273ab618543SJohn Levon 	struct pid	*p_pgidp;
27475cebdd1SRyan Zezeski 	struct cred	*p_cred;
27575cebdd1SRyan Zezeski 	struct sess	*p_sessp;
27675cebdd1SRyan Zezeski 	struct task	*p_task;
27775cebdd1SRyan Zezeski 	struct zone	*p_zone;
27871a582fbSJohn Levon 	struct cont_process *p_ct_process;
27975cebdd1SRyan Zezeski 	pid_t		p_ppid;
28075cebdd1SRyan Zezeski 	uint_t		p_flag;
28175cebdd1SRyan Zezeski 	struct {
28275cebdd1SRyan Zezeski 		char		u_comm[MAXCOMLEN + 1];
28375cebdd1SRyan Zezeski 		char		u_psargs[PSARGSZ];
28475cebdd1SRyan Zezeski 	} p_user;
28575cebdd1SRyan Zezeski } mdb_ps_proc_t;
28675cebdd1SRyan Zezeski 
28771a582fbSJohn Levon /*
28871a582fbSJohn Levon  * A reasonable enough limit. Note that we purposefully let this column over-run
28971a582fbSJohn Levon  * if needed.
29071a582fbSJohn Levon  */
29171a582fbSJohn Levon #define	FMRI_LEN (128)
29271a582fbSJohn Levon 
2937c478bd9Sstevel@tonic-gate int
ps(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2947c478bd9Sstevel@tonic-gate ps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate 	uint_t prt_flags = 0;
29775cebdd1SRyan Zezeski 	mdb_ps_proc_t pr;
2987c478bd9Sstevel@tonic-gate 	struct pid pid, pgid, sid;
2997c478bd9Sstevel@tonic-gate 	sess_t session;
3007c478bd9Sstevel@tonic-gate 	cred_t cred;
3017c478bd9Sstevel@tonic-gate 	task_t tk;
3027c478bd9Sstevel@tonic-gate 	kproject_t pj;
3037c478bd9Sstevel@tonic-gate 	zone_t zn;
30471a582fbSJohn Levon 	struct cont_process cp;
30571a582fbSJohn Levon 	char fmri[FMRI_LEN] = "";
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
3087c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("proc", "ps", argc, argv) == -1) {
3097c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk 'proc'");
3107c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
3117c478bd9Sstevel@tonic-gate 		}
3127c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
3137c478bd9Sstevel@tonic-gate 	}
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
3167c478bd9Sstevel@tonic-gate 	    'f', MDB_OPT_SETBITS, PS_PSARGS, &prt_flags,
3177c478bd9Sstevel@tonic-gate 	    'l', MDB_OPT_SETBITS, PS_PRTLWPS, &prt_flags,
31871a582fbSJohn Levon 	    's', MDB_OPT_SETBITS, PS_SERVICES, &prt_flags,
3197c478bd9Sstevel@tonic-gate 	    'T', MDB_OPT_SETBITS, PS_TASKS, &prt_flags,
3207c478bd9Sstevel@tonic-gate 	    'P', MDB_OPT_SETBITS, PS_PROJECTS, &prt_flags,
3217c478bd9Sstevel@tonic-gate 	    'z', MDB_OPT_SETBITS, PS_ZONES, &prt_flags,
3227c478bd9Sstevel@tonic-gate 	    't', MDB_OPT_SETBITS, PS_PRTTHREADS, &prt_flags, NULL) != argc)
3237c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
32671a582fbSJohn Levon 		mdb_printf("%<u>%-1s %-6s %-6s %-6s %-6s ",
3277c478bd9Sstevel@tonic-gate 		    "S", "PID", "PPID", "PGID", "SID");
3287c478bd9Sstevel@tonic-gate 		if (prt_flags & PS_TASKS)
32971a582fbSJohn Levon 			mdb_printf("%-5s ", "TASK");
3307c478bd9Sstevel@tonic-gate 		if (prt_flags & PS_PROJECTS)
33171a582fbSJohn Levon 			mdb_printf("%-5s ", "PROJ");
3327c478bd9Sstevel@tonic-gate 		if (prt_flags & PS_ZONES)
33371a582fbSJohn Levon 			mdb_printf("%-5s ", "ZONE");
33471a582fbSJohn Levon 		if (prt_flags & PS_SERVICES)
33571a582fbSJohn Levon 			mdb_printf("%-40s ", "SERVICE");
33671a582fbSJohn Levon 		mdb_printf("%-6s %-10s %-?s %-s%</u>\n",
3377c478bd9Sstevel@tonic-gate 		    "UID", "FLAGS", "ADDR", "NAME");
3387c478bd9Sstevel@tonic-gate 	}
3397c478bd9Sstevel@tonic-gate 
34075cebdd1SRyan Zezeski 	if (mdb_ctf_vread(&pr, "proc_t", "mdb_ps_proc_t", addr, 0) == -1)
34175cebdd1SRyan Zezeski 		return (DCMD_ERR);
34275cebdd1SRyan Zezeski 
3437c478bd9Sstevel@tonic-gate 	mdb_vread(&pid, sizeof (pid), (uintptr_t)pr.p_pidp);
3447c478bd9Sstevel@tonic-gate 	mdb_vread(&pgid, sizeof (pgid), (uintptr_t)pr.p_pgidp);
3457c478bd9Sstevel@tonic-gate 	mdb_vread(&cred, sizeof (cred), (uintptr_t)pr.p_cred);
3467c478bd9Sstevel@tonic-gate 	mdb_vread(&session, sizeof (session), (uintptr_t)pr.p_sessp);
3477c478bd9Sstevel@tonic-gate 	mdb_vread(&sid, sizeof (sid), (uintptr_t)session.s_sidp);
3487c478bd9Sstevel@tonic-gate 	if (prt_flags & (PS_TASKS | PS_PROJECTS))
3497c478bd9Sstevel@tonic-gate 		mdb_vread(&tk, sizeof (tk), (uintptr_t)pr.p_task);
3507c478bd9Sstevel@tonic-gate 	if (prt_flags & PS_PROJECTS)
3517c478bd9Sstevel@tonic-gate 		mdb_vread(&pj, sizeof (pj), (uintptr_t)tk.tk_proj);
3527c478bd9Sstevel@tonic-gate 	if (prt_flags & PS_ZONES)
35375cebdd1SRyan Zezeski 		mdb_vread(&zn, sizeof (zn), (uintptr_t)pr.p_zone);
35471a582fbSJohn Levon 	if ((prt_flags & PS_SERVICES) && pr.p_ct_process != NULL) {
35571a582fbSJohn Levon 		mdb_vread(&cp, sizeof (cp), (uintptr_t)pr.p_ct_process);
35671a582fbSJohn Levon 
35771a582fbSJohn Levon 		if (mdb_read_refstr((uintptr_t)cp.conp_svc_fmri, fmri,
35871a582fbSJohn Levon 		    sizeof (fmri)) <= 0)
35971a582fbSJohn Levon 			(void) strlcpy(fmri, "?", sizeof (fmri));
36071a582fbSJohn Levon 
36171a582fbSJohn Levon 		/* Strip any standard prefix and suffix. */
36271a582fbSJohn Levon 		if (strncmp(fmri, "svc:/", sizeof ("svc:/") - 1) == 0) {
36371a582fbSJohn Levon 			char *i = fmri;
36471a582fbSJohn Levon 			char *j = fmri + sizeof ("svc:/") - 1;
36571a582fbSJohn Levon 			for (; *j != '\0'; i++, j++) {
36671a582fbSJohn Levon 				if (strcmp(j, ":default") == 0)
36771a582fbSJohn Levon 					break;
36871a582fbSJohn Levon 				*i = *j;
36971a582fbSJohn Levon 			}
37071a582fbSJohn Levon 
37171a582fbSJohn Levon 			*i = '\0';
37271a582fbSJohn Levon 		}
37371a582fbSJohn Levon 	}
3747c478bd9Sstevel@tonic-gate 
37571a582fbSJohn Levon 	mdb_printf("%-c %-6d %-6d %-6d %-6d ",
3767c478bd9Sstevel@tonic-gate 	    pstat2ch(pr.p_stat), pid.pid_id, pr.p_ppid, pgid.pid_id,
3777c478bd9Sstevel@tonic-gate 	    sid.pid_id);
3787c478bd9Sstevel@tonic-gate 	if (prt_flags & PS_TASKS)
37971a582fbSJohn Levon 		mdb_printf("%-5d ", tk.tk_tkid);
3807c478bd9Sstevel@tonic-gate 	if (prt_flags & PS_PROJECTS)
38171a582fbSJohn Levon 		mdb_printf("%-5d ", pj.kpj_id);
3827c478bd9Sstevel@tonic-gate 	if (prt_flags & PS_ZONES)
38371a582fbSJohn Levon 		mdb_printf("%-5d ", zn.zone_id);
38471a582fbSJohn Levon 	if (prt_flags & PS_SERVICES)
38571a582fbSJohn Levon 		mdb_printf("%-40s ", fmri);
38671a582fbSJohn Levon 	mdb_printf("%-6d 0x%08x %0?p %-s\n",
3877c478bd9Sstevel@tonic-gate 	    cred.cr_uid, pr.p_flag, addr,
3887c478bd9Sstevel@tonic-gate 	    (prt_flags & PS_PSARGS) ? pr.p_user.u_psargs : pr.p_user.u_comm);
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	if (prt_flags & ~PS_PSARGS)
3917c478bd9Sstevel@tonic-gate 		(void) mdb_pwalk("thread", ps_threadprint, &prt_flags, addr);
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
3947c478bd9Sstevel@tonic-gate }
3957c478bd9Sstevel@tonic-gate 
3965a382e8fSJason King static void
ps_help(void)3975a382e8fSJason King ps_help(void)
3985a382e8fSJason King {
3995a382e8fSJason King 	mdb_printf("Display processes.\n\n"
4005a382e8fSJason King 	    "Options:\n"
4015a382e8fSJason King 	    "    -f\tDisplay command arguments\n"
4025a382e8fSJason King 	    "    -l\tDisplay LWPs\n"
4035a382e8fSJason King 	    "    -T\tDisplay tasks\n"
4045a382e8fSJason King 	    "    -P\tDisplay projects\n"
40571a582fbSJohn Levon 	    "    -s\tDisplay SMF FMRI\n"
4065a382e8fSJason King 	    "    -z\tDisplay zones\n"
4075a382e8fSJason King 	    "    -t\tDisplay threads\n\n");
4085a382e8fSJason King 
4095a382e8fSJason King 	mdb_printf("The resulting output is a table of the processes on the "
4105a382e8fSJason King 	    "system.  The\n"
4115a382e8fSJason King 	    "columns in the output consist of a combination of the "
4125a382e8fSJason King 	    "following fields:\n\n");
4135a382e8fSJason King 	mdb_printf("S\tProcess state.  Possible states are:\n"
4145a382e8fSJason King 	    "\tS\tSleeping (SSLEEP)\n"
4155a382e8fSJason King 	    "\tR\tRunnable (SRUN)\n"
4165a382e8fSJason King 	    "\tZ\tZombie (SZOMB)\n"
4175a382e8fSJason King 	    "\tI\tIdle (SIDL)\n"
4185a382e8fSJason King 	    "\tO\tOn Cpu (SONPROC)\n"
4195a382e8fSJason King 	    "\tT\tStopped (SSTOP)\n"
4205a382e8fSJason King 	    "\tW\tWaiting (SWAIT)\n");
4215a382e8fSJason King 
4225a382e8fSJason King 	mdb_printf("PID\tProcess id.\n");
4235a382e8fSJason King 	mdb_printf("PPID\tParent process id.\n");
4245a382e8fSJason King 	mdb_printf("PGID\tProcess group id.\n");
4255a382e8fSJason King 	mdb_printf("SID\tProcess id of the session leader.\n");
4265a382e8fSJason King 	mdb_printf("TASK\tThe task id of the process.\n");
4275a382e8fSJason King 	mdb_printf("PROJ\tThe project id of the process.\n");
4285a382e8fSJason King 	mdb_printf("ZONE\tThe zone id of the process.\n");
42971a582fbSJohn Levon 	mdb_printf("SERVICE The SMF service FMRI of the process.\n");
4305a382e8fSJason King 	mdb_printf("UID\tThe user id of the process.\n");
4315a382e8fSJason King 	mdb_printf("FLAGS\tThe process flags (see ::pflags).\n");
4325a382e8fSJason King 	mdb_printf("ADDR\tThe kernel address of the proc_t structure of the "
4335a382e8fSJason King 	    "process\n");
4345a382e8fSJason King 	mdb_printf("NAME\tThe name (p_user.u_comm field) of the process.  If "
4355a382e8fSJason King 	    "the -f flag\n"
4365a382e8fSJason King 	    "\tis specified, the arguments of the process are displayed.\n");
4375a382e8fSJason King }
4385a382e8fSJason King 
4397c478bd9Sstevel@tonic-gate #define	PG_NEWEST	0x0001
4407c478bd9Sstevel@tonic-gate #define	PG_OLDEST	0x0002
4417c478bd9Sstevel@tonic-gate #define	PG_PIPE_OUT	0x0004
442adb664e2Svb #define	PG_EXACT_MATCH	0x0008
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate typedef struct pgrep_data {
4457c478bd9Sstevel@tonic-gate 	uint_t pg_flags;
4467c478bd9Sstevel@tonic-gate 	uint_t pg_psflags;
4477c478bd9Sstevel@tonic-gate 	uintptr_t pg_xaddr;
4487c478bd9Sstevel@tonic-gate 	hrtime_t pg_xstart;
4497c478bd9Sstevel@tonic-gate 	const char *pg_pat;
4507c478bd9Sstevel@tonic-gate #ifndef _KMDB
4517c478bd9Sstevel@tonic-gate 	regex_t pg_reg;
4527c478bd9Sstevel@tonic-gate #endif
4537c478bd9Sstevel@tonic-gate } pgrep_data_t;
4547c478bd9Sstevel@tonic-gate 
45575cebdd1SRyan Zezeski typedef struct mdb_pgrep_proc {
45675cebdd1SRyan Zezeski 	struct {
45775cebdd1SRyan Zezeski 		timestruc_t	u_start;
45875cebdd1SRyan Zezeski 		char		u_comm[MAXCOMLEN + 1];
45975cebdd1SRyan Zezeski 	} p_user;
46075cebdd1SRyan Zezeski } mdb_pgrep_proc_t;
46175cebdd1SRyan Zezeski 
4627c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4637c478bd9Sstevel@tonic-gate static int
pgrep_cb(uintptr_t addr,const void * ignored,void * data)46475cebdd1SRyan Zezeski pgrep_cb(uintptr_t addr, const void *ignored, void *data)
4657c478bd9Sstevel@tonic-gate {
46675cebdd1SRyan Zezeski 	mdb_pgrep_proc_t p;
4677c478bd9Sstevel@tonic-gate 	pgrep_data_t *pgp = data;
4687c478bd9Sstevel@tonic-gate #ifndef _KMDB
4697c478bd9Sstevel@tonic-gate 	regmatch_t pmatch;
4707c478bd9Sstevel@tonic-gate #endif
4717c478bd9Sstevel@tonic-gate 
47275cebdd1SRyan Zezeski 	if (mdb_ctf_vread(&p, "proc_t", "mdb_pgrep_proc_t", addr, 0) == -1)
47375cebdd1SRyan Zezeski 		return (WALK_ERR);
47475cebdd1SRyan Zezeski 
4757c478bd9Sstevel@tonic-gate 	/*
4767c478bd9Sstevel@tonic-gate 	 * kmdb doesn't have access to the reg* functions, so we fall back
477adb664e2Svb 	 * to strstr/strcmp.
4787c478bd9Sstevel@tonic-gate 	 */
4797c478bd9Sstevel@tonic-gate #ifdef _KMDB
480adb664e2Svb 	if ((pgp->pg_flags & PG_EXACT_MATCH) ?
48175cebdd1SRyan Zezeski 	    (strcmp(p.p_user.u_comm, pgp->pg_pat) != 0) :
48275cebdd1SRyan Zezeski 	    (strstr(p.p_user.u_comm, pgp->pg_pat) == NULL))
4837c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
4847c478bd9Sstevel@tonic-gate #else
48575cebdd1SRyan Zezeski 	if (regexec(&pgp->pg_reg, p.p_user.u_comm, 1, &pmatch, 0) != 0)
4867c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
487adb664e2Svb 
488adb664e2Svb 	if ((pgp->pg_flags & PG_EXACT_MATCH) &&
48975cebdd1SRyan Zezeski 	    (pmatch.rm_so != 0 || p.p_user.u_comm[pmatch.rm_eo] != '\0'))
490adb664e2Svb 		return (WALK_NEXT);
4917c478bd9Sstevel@tonic-gate #endif
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 	if (pgp->pg_flags & (PG_NEWEST | PG_OLDEST)) {
4947c478bd9Sstevel@tonic-gate 		hrtime_t start;
4957c478bd9Sstevel@tonic-gate 
49675cebdd1SRyan Zezeski 		start = (hrtime_t)p.p_user.u_start.tv_sec * NANOSEC +
49775cebdd1SRyan Zezeski 		    p.p_user.u_start.tv_nsec;
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 		if (pgp->pg_flags & PG_NEWEST) {
500892ad162SToomas Soome 			if (pgp->pg_xaddr == 0 || start > pgp->pg_xstart) {
5017c478bd9Sstevel@tonic-gate 				pgp->pg_xaddr = addr;
5027c478bd9Sstevel@tonic-gate 				pgp->pg_xstart = start;
5037c478bd9Sstevel@tonic-gate 			}
5047c478bd9Sstevel@tonic-gate 		} else {
505892ad162SToomas Soome 			if (pgp->pg_xaddr == 0 || start < pgp->pg_xstart) {
5067c478bd9Sstevel@tonic-gate 				pgp->pg_xaddr = addr;
5077c478bd9Sstevel@tonic-gate 				pgp->pg_xstart = start;
5087c478bd9Sstevel@tonic-gate 			}
5097c478bd9Sstevel@tonic-gate 		}
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 	} else if (pgp->pg_flags & PG_PIPE_OUT) {
5127c478bd9Sstevel@tonic-gate 		mdb_printf("%p\n", addr);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	} else {
5157c478bd9Sstevel@tonic-gate 		if (mdb_call_dcmd("ps", addr, pgp->pg_psflags, 0, NULL) != 0) {
5167c478bd9Sstevel@tonic-gate 			mdb_warn("can't invoke 'ps'");
5177c478bd9Sstevel@tonic-gate 			return (WALK_DONE);
5187c478bd9Sstevel@tonic-gate 		}
5197c478bd9Sstevel@tonic-gate 		pgp->pg_psflags &= ~DCMD_LOOPFIRST;
5207c478bd9Sstevel@tonic-gate 	}
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5267c478bd9Sstevel@tonic-gate int
pgrep(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5277c478bd9Sstevel@tonic-gate pgrep(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5287c478bd9Sstevel@tonic-gate {
5297c478bd9Sstevel@tonic-gate 	pgrep_data_t pg;
5307c478bd9Sstevel@tonic-gate 	int i;
5317c478bd9Sstevel@tonic-gate #ifndef _KMDB
5327c478bd9Sstevel@tonic-gate 	int err;
5337c478bd9Sstevel@tonic-gate #endif
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC)
5367c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	pg.pg_flags = 0;
5397c478bd9Sstevel@tonic-gate 	pg.pg_xaddr = 0;
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 	i = mdb_getopts(argc, argv,
5427c478bd9Sstevel@tonic-gate 	    'n', MDB_OPT_SETBITS, PG_NEWEST, &pg.pg_flags,
5437c478bd9Sstevel@tonic-gate 	    'o', MDB_OPT_SETBITS, PG_OLDEST, &pg.pg_flags,
544adb664e2Svb 	    'x', MDB_OPT_SETBITS, PG_EXACT_MATCH, &pg.pg_flags,
5457c478bd9Sstevel@tonic-gate 	    NULL);
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	argc -= i;
5487c478bd9Sstevel@tonic-gate 	argv += i;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	if (argc != 1)
5517c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	/*
5547c478bd9Sstevel@tonic-gate 	 * -n and -o are mutually exclusive.
5557c478bd9Sstevel@tonic-gate 	 */
5567c478bd9Sstevel@tonic-gate 	if ((pg.pg_flags & PG_NEWEST) && (pg.pg_flags & PG_OLDEST))
5577c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 	if (argv->a_type != MDB_TYPE_STRING)
5607c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	if (flags & DCMD_PIPE_OUT)
5637c478bd9Sstevel@tonic-gate 		pg.pg_flags |= PG_PIPE_OUT;
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate 	pg.pg_pat = argv->a_un.a_str;
5667c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
5677c478bd9Sstevel@tonic-gate 		pg.pg_psflags = DCMD_ADDRSPEC | DCMD_LOOP | DCMD_LOOPFIRST;
5687c478bd9Sstevel@tonic-gate 	else
5697c478bd9Sstevel@tonic-gate 		pg.pg_psflags = DCMD_ADDRSPEC | DCMD_LOOP;
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate #ifndef _KMDB
5727c478bd9Sstevel@tonic-gate 	if ((err = regcomp(&pg.pg_reg, pg.pg_pat, REG_EXTENDED)) != 0) {
5737c478bd9Sstevel@tonic-gate 		size_t nbytes;
5747c478bd9Sstevel@tonic-gate 		char *buf;
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 		nbytes = regerror(err, &pg.pg_reg, NULL, 0);
5777c478bd9Sstevel@tonic-gate 		buf = mdb_alloc(nbytes + 1, UM_SLEEP | UM_GC);
5787c478bd9Sstevel@tonic-gate 		(void) regerror(err, &pg.pg_reg, buf, nbytes);
5797c478bd9Sstevel@tonic-gate 		mdb_warn("%s\n", buf);
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate #endif
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 	if (mdb_walk("proc", pgrep_cb, &pg) != 0) {
5867c478bd9Sstevel@tonic-gate 		mdb_warn("can't walk 'proc'");
5877c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5887c478bd9Sstevel@tonic-gate 	}
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	if (pg.pg_xaddr != 0 && (pg.pg_flags & (PG_NEWEST | PG_OLDEST))) {
5917c478bd9Sstevel@tonic-gate 		if (pg.pg_flags & PG_PIPE_OUT) {
5927c478bd9Sstevel@tonic-gate 			mdb_printf("%p\n", pg.pg_xaddr);
5937c478bd9Sstevel@tonic-gate 		} else {
5947c478bd9Sstevel@tonic-gate 			if (mdb_call_dcmd("ps", pg.pg_xaddr, pg.pg_psflags,
5957c478bd9Sstevel@tonic-gate 			    0, NULL) != 0) {
5967c478bd9Sstevel@tonic-gate 				mdb_warn("can't invoke 'ps'");
5977c478bd9Sstevel@tonic-gate 				return (DCMD_ERR);
5987c478bd9Sstevel@tonic-gate 			}
5997c478bd9Sstevel@tonic-gate 		}
6007c478bd9Sstevel@tonic-gate 	}
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
6037c478bd9Sstevel@tonic-gate }
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate int
task(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6067c478bd9Sstevel@tonic-gate task(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6077c478bd9Sstevel@tonic-gate {
6087c478bd9Sstevel@tonic-gate 	task_t tk;
6097c478bd9Sstevel@tonic-gate 	kproject_t pj;
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
6127c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("task_cache", "task", argc, argv) == -1) {
6137c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk task_cache");
6147c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
6157c478bd9Sstevel@tonic-gate 		}
6167c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
6177c478bd9Sstevel@tonic-gate 	}
6187c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
6197c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%?s %6s %6s %6s %6s %10s%</u>\n",
6207c478bd9Sstevel@tonic-gate 		    "ADDR", "TASKID", "PROJID", "ZONEID", "REFCNT", "FLAGS");
6217c478bd9Sstevel@tonic-gate 	}
6227c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tk, sizeof (task_t), addr) == -1) {
6237c478bd9Sstevel@tonic-gate 		mdb_warn("can't read task_t structure at %p", addr);
6247c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6257c478bd9Sstevel@tonic-gate 	}
6267c478bd9Sstevel@tonic-gate 	if (mdb_vread(&pj, sizeof (kproject_t), (uintptr_t)tk.tk_proj) == -1) {
6277c478bd9Sstevel@tonic-gate 		mdb_warn("can't read project_t structure at %p", addr);
6287c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6297c478bd9Sstevel@tonic-gate 	}
6307c478bd9Sstevel@tonic-gate 	mdb_printf("%0?p %6d %6d %6d %6u 0x%08x\n",
6317c478bd9Sstevel@tonic-gate 	    addr, tk.tk_tkid, pj.kpj_id, pj.kpj_zoneid, tk.tk_hold_count,
6327c478bd9Sstevel@tonic-gate 	    tk.tk_flags);
6337c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate int
project(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6377c478bd9Sstevel@tonic-gate project(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6387c478bd9Sstevel@tonic-gate {
6397c478bd9Sstevel@tonic-gate 	kproject_t pj;
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
6427c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("projects", "project", argc, argv) == -1) {
6437c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk projects");
6447c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
6457c478bd9Sstevel@tonic-gate 		}
6467c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
6477c478bd9Sstevel@tonic-gate 	}
6487c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
6497c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%?s %6s %6s %6s%</u>\n",
6507c478bd9Sstevel@tonic-gate 		    "ADDR", "PROJID", "ZONEID", "REFCNT");
6517c478bd9Sstevel@tonic-gate 	}
6527c478bd9Sstevel@tonic-gate 	if (mdb_vread(&pj, sizeof (kproject_t), addr) == -1) {
6537c478bd9Sstevel@tonic-gate 		mdb_warn("can't read kproject_t structure at %p", addr);
6547c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6557c478bd9Sstevel@tonic-gate 	}
6567c478bd9Sstevel@tonic-gate 	mdb_printf("%0?p %6d %6d %6u\n", addr, pj.kpj_id, pj.kpj_zoneid,
6577c478bd9Sstevel@tonic-gate 	    pj.kpj_count);
6587c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate 
66187a18d3fSMadhavan Venkataraman /* walk callouts themselves, either by list or id hash. */
6627c478bd9Sstevel@tonic-gate int
callout_walk_init(mdb_walk_state_t * wsp)66387a18d3fSMadhavan Venkataraman callout_walk_init(mdb_walk_state_t *wsp)
6647c478bd9Sstevel@tonic-gate {
665892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
66687a18d3fSMadhavan Venkataraman 		mdb_warn("callout doesn't support global walk");
66787a18d3fSMadhavan Venkataraman 		return (WALK_ERR);
66887a18d3fSMadhavan Venkataraman 	}
66987a18d3fSMadhavan Venkataraman 	wsp->walk_data = mdb_alloc(sizeof (callout_t), UM_SLEEP);
67087a18d3fSMadhavan Venkataraman 	return (WALK_NEXT);
67187a18d3fSMadhavan Venkataraman }
6727c478bd9Sstevel@tonic-gate 
67387a18d3fSMadhavan Venkataraman #define	CALLOUT_WALK_BYLIST	0
67487a18d3fSMadhavan Venkataraman #define	CALLOUT_WALK_BYID	1
67587a18d3fSMadhavan Venkataraman 
67687a18d3fSMadhavan Venkataraman /* the walker arg switches between walking by list (0) and walking by id (1). */
67787a18d3fSMadhavan Venkataraman int
callout_walk_step(mdb_walk_state_t * wsp)67887a18d3fSMadhavan Venkataraman callout_walk_step(mdb_walk_state_t *wsp)
67987a18d3fSMadhavan Venkataraman {
68087a18d3fSMadhavan Venkataraman 	int retval;
6817c478bd9Sstevel@tonic-gate 
682892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
68387a18d3fSMadhavan Venkataraman 		return (WALK_DONE);
68487a18d3fSMadhavan Venkataraman 	}
68587a18d3fSMadhavan Venkataraman 	if (mdb_vread(wsp->walk_data, sizeof (callout_t),
68687a18d3fSMadhavan Venkataraman 	    wsp->walk_addr) == -1) {
68787a18d3fSMadhavan Venkataraman 		mdb_warn("failed to read callout at %p", wsp->walk_addr);
68887a18d3fSMadhavan Venkataraman 		return (WALK_DONE);
68987a18d3fSMadhavan Venkataraman 	}
69087a18d3fSMadhavan Venkataraman 	retval = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
69187a18d3fSMadhavan Venkataraman 	    wsp->walk_cbdata);
69287a18d3fSMadhavan Venkataraman 
69387a18d3fSMadhavan Venkataraman 	if ((ulong_t)wsp->walk_arg == CALLOUT_WALK_BYID) {
69487a18d3fSMadhavan Venkataraman 		wsp->walk_addr =
69587a18d3fSMadhavan Venkataraman 		    (uintptr_t)(((callout_t *)wsp->walk_data)->c_idnext);
696843e1988Sjohnlev 	} else {
69787a18d3fSMadhavan Venkataraman 		wsp->walk_addr =
69887a18d3fSMadhavan Venkataraman 		    (uintptr_t)(((callout_t *)wsp->walk_data)->c_clnext);
699843e1988Sjohnlev 	}
7007c478bd9Sstevel@tonic-gate 
70187a18d3fSMadhavan Venkataraman 	return (retval);
70287a18d3fSMadhavan Venkataraman }
70387a18d3fSMadhavan Venkataraman 
70487a18d3fSMadhavan Venkataraman void
callout_walk_fini(mdb_walk_state_t * wsp)70587a18d3fSMadhavan Venkataraman callout_walk_fini(mdb_walk_state_t *wsp)
70687a18d3fSMadhavan Venkataraman {
70787a18d3fSMadhavan Venkataraman 	mdb_free(wsp->walk_data, sizeof (callout_t));
70887a18d3fSMadhavan Venkataraman }
70987a18d3fSMadhavan Venkataraman 
71087a18d3fSMadhavan Venkataraman /*
71187a18d3fSMadhavan Venkataraman  * walker for callout lists. This is different from hashes and callouts.
71287a18d3fSMadhavan Venkataraman  * Thankfully, it's also simpler.
71387a18d3fSMadhavan Venkataraman  */
71487a18d3fSMadhavan Venkataraman int
callout_list_walk_init(mdb_walk_state_t * wsp)71587a18d3fSMadhavan Venkataraman callout_list_walk_init(mdb_walk_state_t *wsp)
71687a18d3fSMadhavan Venkataraman {
717892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
71887a18d3fSMadhavan Venkataraman 		mdb_warn("callout list doesn't support global walk");
71987a18d3fSMadhavan Venkataraman 		return (WALK_ERR);
7207c478bd9Sstevel@tonic-gate 	}
72187a18d3fSMadhavan Venkataraman 	wsp->walk_data = mdb_alloc(sizeof (callout_list_t), UM_SLEEP);
72287a18d3fSMadhavan Venkataraman 	return (WALK_NEXT);
72387a18d3fSMadhavan Venkataraman }
7247c478bd9Sstevel@tonic-gate 
72587a18d3fSMadhavan Venkataraman int
callout_list_walk_step(mdb_walk_state_t * wsp)72687a18d3fSMadhavan Venkataraman callout_list_walk_step(mdb_walk_state_t *wsp)
72787a18d3fSMadhavan Venkataraman {
72887a18d3fSMadhavan Venkataraman 	int retval;
72987a18d3fSMadhavan Venkataraman 
730892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
73187a18d3fSMadhavan Venkataraman 		return (WALK_DONE);
7327c478bd9Sstevel@tonic-gate 	}
73387a18d3fSMadhavan Venkataraman 	if (mdb_vread(wsp->walk_data, sizeof (callout_list_t),
73487a18d3fSMadhavan Venkataraman 	    wsp->walk_addr) != sizeof (callout_list_t)) {
73587a18d3fSMadhavan Venkataraman 		mdb_warn("failed to read callout_list at %p", wsp->walk_addr);
73687a18d3fSMadhavan Venkataraman 		return (WALK_ERR);
73787a18d3fSMadhavan Venkataraman 	}
73887a18d3fSMadhavan Venkataraman 	retval = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
73987a18d3fSMadhavan Venkataraman 	    wsp->walk_cbdata);
7407c478bd9Sstevel@tonic-gate 
74187a18d3fSMadhavan Venkataraman 	wsp->walk_addr = (uintptr_t)
74287a18d3fSMadhavan Venkataraman 	    (((callout_list_t *)wsp->walk_data)->cl_next);
74387a18d3fSMadhavan Venkataraman 
74487a18d3fSMadhavan Venkataraman 	return (retval);
74587a18d3fSMadhavan Venkataraman }
74687a18d3fSMadhavan Venkataraman 
74787a18d3fSMadhavan Venkataraman void
callout_list_walk_fini(mdb_walk_state_t * wsp)74887a18d3fSMadhavan Venkataraman callout_list_walk_fini(mdb_walk_state_t *wsp)
74987a18d3fSMadhavan Venkataraman {
75087a18d3fSMadhavan Venkataraman 	mdb_free(wsp->walk_data, sizeof (callout_list_t));
75187a18d3fSMadhavan Venkataraman }
75287a18d3fSMadhavan Venkataraman 
75387a18d3fSMadhavan Venkataraman /* routines/structs to walk callout table(s) */
75487a18d3fSMadhavan Venkataraman typedef struct cot_data {
75587a18d3fSMadhavan Venkataraman 	callout_table_t *ct0;
75687a18d3fSMadhavan Venkataraman 	callout_table_t ct;
75787a18d3fSMadhavan Venkataraman 	callout_hash_t cot_idhash[CALLOUT_BUCKETS];
75887a18d3fSMadhavan Venkataraman 	callout_hash_t cot_clhash[CALLOUT_BUCKETS];
75987a18d3fSMadhavan Venkataraman 	kstat_named_t ct_kstat_data[CALLOUT_NUM_STATS];
76087a18d3fSMadhavan Venkataraman 	int cotndx;
76187a18d3fSMadhavan Venkataraman 	int cotsize;
76287a18d3fSMadhavan Venkataraman } cot_data_t;
76387a18d3fSMadhavan Venkataraman 
76487a18d3fSMadhavan Venkataraman int
callout_table_walk_init(mdb_walk_state_t * wsp)76587a18d3fSMadhavan Venkataraman callout_table_walk_init(mdb_walk_state_t *wsp)
76687a18d3fSMadhavan Venkataraman {
76787a18d3fSMadhavan Venkataraman 	int max_ncpus;
76887a18d3fSMadhavan Venkataraman 	cot_data_t *cot_walk_data;
76987a18d3fSMadhavan Venkataraman 
77087a18d3fSMadhavan Venkataraman 	cot_walk_data = mdb_alloc(sizeof (cot_data_t), UM_SLEEP);
77187a18d3fSMadhavan Venkataraman 
772892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
77387a18d3fSMadhavan Venkataraman 		if (mdb_readvar(&cot_walk_data->ct0, "callout_table") == -1) {
77487a18d3fSMadhavan Venkataraman 			mdb_warn("failed to read 'callout_table'");
77587a18d3fSMadhavan Venkataraman 			return (WALK_ERR);
77687a18d3fSMadhavan Venkataraman 		}
77787a18d3fSMadhavan Venkataraman 		if (mdb_readvar(&max_ncpus, "max_ncpus") == -1) {
77887a18d3fSMadhavan Venkataraman 			mdb_warn("failed to get callout_table array size");
77987a18d3fSMadhavan Venkataraman 			return (WALK_ERR);
78087a18d3fSMadhavan Venkataraman 		}
78187a18d3fSMadhavan Venkataraman 		cot_walk_data->cotsize = CALLOUT_NTYPES * max_ncpus;
78287a18d3fSMadhavan Venkataraman 		wsp->walk_addr = (uintptr_t)cot_walk_data->ct0;
78387a18d3fSMadhavan Venkataraman 	} else {
78487a18d3fSMadhavan Venkataraman 		/* not a global walk */
78587a18d3fSMadhavan Venkataraman 		cot_walk_data->cotsize = 1;
7867c478bd9Sstevel@tonic-gate 	}
7877c478bd9Sstevel@tonic-gate 
78887a18d3fSMadhavan Venkataraman 	cot_walk_data->cotndx = 0;
78987a18d3fSMadhavan Venkataraman 	wsp->walk_data = cot_walk_data;
7907c478bd9Sstevel@tonic-gate 
79187a18d3fSMadhavan Venkataraman 	return (WALK_NEXT);
79287a18d3fSMadhavan Venkataraman }
7937c478bd9Sstevel@tonic-gate 
79487a18d3fSMadhavan Venkataraman int
callout_table_walk_step(mdb_walk_state_t * wsp)79587a18d3fSMadhavan Venkataraman callout_table_walk_step(mdb_walk_state_t *wsp)
79687a18d3fSMadhavan Venkataraman {
79787a18d3fSMadhavan Venkataraman 	int retval;
79887a18d3fSMadhavan Venkataraman 	cot_data_t *cotwd = (cot_data_t *)wsp->walk_data;
79987a18d3fSMadhavan Venkataraman 	size_t size;
8007c478bd9Sstevel@tonic-gate 
80187a18d3fSMadhavan Venkataraman 	if (cotwd->cotndx >= cotwd->cotsize) {
80287a18d3fSMadhavan Venkataraman 		return (WALK_DONE);
80387a18d3fSMadhavan Venkataraman 	}
80487a18d3fSMadhavan Venkataraman 	if (mdb_vread(&(cotwd->ct), sizeof (callout_table_t),
80587a18d3fSMadhavan Venkataraman 	    wsp->walk_addr) != sizeof (callout_table_t)) {
80687a18d3fSMadhavan Venkataraman 		mdb_warn("failed to read callout_table at %p", wsp->walk_addr);
80787a18d3fSMadhavan Venkataraman 		return (WALK_ERR);
80887a18d3fSMadhavan Venkataraman 	}
80987a18d3fSMadhavan Venkataraman 
81087a18d3fSMadhavan Venkataraman 	size = sizeof (callout_hash_t) * CALLOUT_BUCKETS;
81187a18d3fSMadhavan Venkataraman 	if (cotwd->ct.ct_idhash != NULL) {
81287a18d3fSMadhavan Venkataraman 		if (mdb_vread(cotwd->cot_idhash, size,
81387a18d3fSMadhavan Venkataraman 		    (uintptr_t)(cotwd->ct.ct_idhash)) != size) {
81487a18d3fSMadhavan Venkataraman 			mdb_warn("failed to read id_hash at %p",
81587a18d3fSMadhavan Venkataraman 			    cotwd->ct.ct_idhash);
81687a18d3fSMadhavan Venkataraman 			return (WALK_ERR);
81787a18d3fSMadhavan Venkataraman 		}
81887a18d3fSMadhavan Venkataraman 	}
81987a18d3fSMadhavan Venkataraman 	if (cotwd->ct.ct_clhash != NULL) {
82087a18d3fSMadhavan Venkataraman 		if (mdb_vread(&(cotwd->cot_clhash), size,
82187a18d3fSMadhavan Venkataraman 		    (uintptr_t)cotwd->ct.ct_clhash) == -1) {
82287a18d3fSMadhavan Venkataraman 			mdb_warn("failed to read cl_hash at %p",
82387a18d3fSMadhavan Venkataraman 			    cotwd->ct.ct_clhash);
82487a18d3fSMadhavan Venkataraman 			return (WALK_ERR);
82587a18d3fSMadhavan Venkataraman 		}
82687a18d3fSMadhavan Venkataraman 	}
82787a18d3fSMadhavan Venkataraman 	size = sizeof (kstat_named_t) * CALLOUT_NUM_STATS;
82887a18d3fSMadhavan Venkataraman 	if (cotwd->ct.ct_kstat_data != NULL) {
82987a18d3fSMadhavan Venkataraman 		if (mdb_vread(&(cotwd->ct_kstat_data), size,
83087a18d3fSMadhavan Venkataraman 		    (uintptr_t)cotwd->ct.ct_kstat_data) == -1) {
83187a18d3fSMadhavan Venkataraman 			mdb_warn("failed to read kstats at %p",
83287a18d3fSMadhavan Venkataraman 			    cotwd->ct.ct_kstat_data);
83387a18d3fSMadhavan Venkataraman 			return (WALK_ERR);
83487a18d3fSMadhavan Venkataraman 		}
83587a18d3fSMadhavan Venkataraman 	}
83687a18d3fSMadhavan Venkataraman 	retval = wsp->walk_callback(wsp->walk_addr, (void *)cotwd,
83787a18d3fSMadhavan Venkataraman 	    wsp->walk_cbdata);
83887a18d3fSMadhavan Venkataraman 
83987a18d3fSMadhavan Venkataraman 	cotwd->cotndx++;
84087a18d3fSMadhavan Venkataraman 	if (cotwd->cotndx >= cotwd->cotsize) {
84187a18d3fSMadhavan Venkataraman 		return (WALK_DONE);
84287a18d3fSMadhavan Venkataraman 	}
84387a18d3fSMadhavan Venkataraman 	wsp->walk_addr = (uintptr_t)((char *)wsp->walk_addr +
84487a18d3fSMadhavan Venkataraman 	    sizeof (callout_table_t));
84587a18d3fSMadhavan Venkataraman 
84687a18d3fSMadhavan Venkataraman 	return (retval);
84787a18d3fSMadhavan Venkataraman }
84887a18d3fSMadhavan Venkataraman 
84987a18d3fSMadhavan Venkataraman void
callout_table_walk_fini(mdb_walk_state_t * wsp)85087a18d3fSMadhavan Venkataraman callout_table_walk_fini(mdb_walk_state_t *wsp)
85187a18d3fSMadhavan Venkataraman {
85287a18d3fSMadhavan Venkataraman 	mdb_free(wsp->walk_data, sizeof (cot_data_t));
85387a18d3fSMadhavan Venkataraman }
85487a18d3fSMadhavan Venkataraman 
85587a18d3fSMadhavan Venkataraman static const char *co_typenames[] = { "R", "N" };
85687a18d3fSMadhavan Venkataraman 
85707247649SMadhavan Venkataraman #define	CO_PLAIN_ID(xid)	((xid) & CALLOUT_ID_MASK)
85887a18d3fSMadhavan Venkataraman 
85987a18d3fSMadhavan Venkataraman #define	TABLE_TO_SEQID(x)	((x) >> CALLOUT_TYPE_BITS)
86087a18d3fSMadhavan Venkataraman 
86187a18d3fSMadhavan Venkataraman /* callout flags, in no particular order */
862060cedfbSMadhavan Venkataraman #define	COF_REAL	0x00000001
863060cedfbSMadhavan Venkataraman #define	COF_NORM	0x00000002
864060cedfbSMadhavan Venkataraman #define	COF_LONG	0x00000004
865060cedfbSMadhavan Venkataraman #define	COF_SHORT	0x00000008
866060cedfbSMadhavan Venkataraman #define	COF_EMPTY	0x00000010
867060cedfbSMadhavan Venkataraman #define	COF_TIME	0x00000020
868060cedfbSMadhavan Venkataraman #define	COF_BEFORE	0x00000040
869060cedfbSMadhavan Venkataraman #define	COF_AFTER	0x00000080
870060cedfbSMadhavan Venkataraman #define	COF_SEQID	0x00000100
871060cedfbSMadhavan Venkataraman #define	COF_FUNC	0x00000200
872060cedfbSMadhavan Venkataraman #define	COF_ADDR	0x00000400
873060cedfbSMadhavan Venkataraman #define	COF_EXEC	0x00000800
874060cedfbSMadhavan Venkataraman #define	COF_HIRES	0x00001000
875060cedfbSMadhavan Venkataraman #define	COF_ABS		0x00002000
876060cedfbSMadhavan Venkataraman #define	COF_TABLE	0x00004000
877060cedfbSMadhavan Venkataraman #define	COF_BYIDH	0x00008000
878060cedfbSMadhavan Venkataraman #define	COF_FREE	0x00010000
879060cedfbSMadhavan Venkataraman #define	COF_LIST	0x00020000
880060cedfbSMadhavan Venkataraman #define	COF_EXPREL	0x00040000
881060cedfbSMadhavan Venkataraman #define	COF_HDR		0x00080000
882060cedfbSMadhavan Venkataraman #define	COF_VERBOSE	0x00100000
883060cedfbSMadhavan Venkataraman #define	COF_LONGLIST	0x00200000
884060cedfbSMadhavan Venkataraman #define	COF_THDR	0x00400000
885060cedfbSMadhavan Venkataraman #define	COF_LHDR	0x00800000
886060cedfbSMadhavan Venkataraman #define	COF_CHDR	0x01000000
887060cedfbSMadhavan Venkataraman #define	COF_PARAM	0x02000000
888060cedfbSMadhavan Venkataraman #define	COF_DECODE	0x04000000
889060cedfbSMadhavan Venkataraman #define	COF_HEAP	0x08000000
890060cedfbSMadhavan Venkataraman #define	COF_QUEUE	0x10000000
89187a18d3fSMadhavan Venkataraman 
89287a18d3fSMadhavan Venkataraman /* show real and normal, short and long, expired and unexpired. */
89387a18d3fSMadhavan Venkataraman #define	COF_DEFAULT	(COF_REAL | COF_NORM | COF_LONG | COF_SHORT)
89487a18d3fSMadhavan Venkataraman 
89551b32bddSMadhavan Venkataraman #define	COF_LIST_FLAGS	\
89651b32bddSMadhavan Venkataraman 	(CALLOUT_LIST_FLAG_HRESTIME | CALLOUT_LIST_FLAG_ABSOLUTE)
89751b32bddSMadhavan Venkataraman 
89887a18d3fSMadhavan Venkataraman /* private callout data for callback functions */
89987a18d3fSMadhavan Venkataraman typedef struct callout_data {
90087a18d3fSMadhavan Venkataraman 	uint_t flags;		/* COF_* */
90187a18d3fSMadhavan Venkataraman 	cpu_t *cpu;		/* cpu pointer if given */
90287a18d3fSMadhavan Venkataraman 	int seqid;		/* cpu seqid, or -1 */
90387a18d3fSMadhavan Venkataraman 	hrtime_t time;		/* expiration time value */
90487a18d3fSMadhavan Venkataraman 	hrtime_t atime;		/* expiration before value */
90587a18d3fSMadhavan Venkataraman 	hrtime_t btime;		/* expiration after value */
90687a18d3fSMadhavan Venkataraman 	uintptr_t funcaddr;	/* function address or NULL */
90787a18d3fSMadhavan Venkataraman 	uintptr_t param;	/* parameter to function or NULL */
908