xref: /titanic_52/usr/src/cmd/mdb/common/modules/nca/nca.c (revision d3d50737e566cade9a08d73d2af95105ac7cd960)
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
5*d3d50737SRafael Vanoni  * Common Development and Distribution License (the "License").
6*d3d50737SRafael Vanoni  * 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 /*
22*d3d50737SRafael Vanoni  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * NCA mdb module.  Provides a collection of dcmds and walkers that
287c478bd9Sstevel@tonic-gate  * operate on core NCA data structures.  Dependencies on NCA internals
297c478bd9Sstevel@tonic-gate  * are described in $SRC/uts/common/inet/nca/nca.h.
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
337c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #include <ctype.h>
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
387c478bd9Sstevel@tonic-gate #include <sys/processor.h>
397c478bd9Sstevel@tonic-gate #include <netinet/in.h>
407c478bd9Sstevel@tonic-gate #include <netinet/ip6.h>	/* must come before common.h */
417c478bd9Sstevel@tonic-gate #include <inet/common.h>	/* must come before led.h */
427c478bd9Sstevel@tonic-gate #include <inet/led.h>		/* must come before ip.h */
437c478bd9Sstevel@tonic-gate #include <inet/ip.h>		/* must come before tcp.h */
447c478bd9Sstevel@tonic-gate #include <inet/tcp.h>		/* must come before nca/nca.h */
457c478bd9Sstevel@tonic-gate #include <inet/nca/nca.h>
467c478bd9Sstevel@tonic-gate #include <inet/nca/ncadoorhdr.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #define	NCA_WALK_PLRU	(void *)1
497c478bd9Sstevel@tonic-gate #define	NCA_WALK_VLRU	(void *)2
507c478bd9Sstevel@tonic-gate #define	NCA_ADDR_WIDTH	11	/* kernel addresses *shouldn't* be wider */
517c478bd9Sstevel@tonic-gate #define	YESNO(bool)	((bool) ? 'Y' : 'n')
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate  * Structure for assigning a name to a region of memory.
557c478bd9Sstevel@tonic-gate  */
567c478bd9Sstevel@tonic-gate typedef struct {
577c478bd9Sstevel@tonic-gate 	const char	*nm_name;	/* name of region */
587c478bd9Sstevel@tonic-gate 	int		nm_len;		/* length to region */
597c478bd9Sstevel@tonic-gate 	uintptr_t	nm_addr;	/* starting address of region */
607c478bd9Sstevel@tonic-gate } namedmem_t;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate  * Structure for giving a name to a constant.
647c478bd9Sstevel@tonic-gate  */
657c478bd9Sstevel@tonic-gate typedef struct {
667c478bd9Sstevel@tonic-gate 	const char *const_name;  /* name of constant */
677c478bd9Sstevel@tonic-gate 	int	    const_value; /* constant itself */
687c478bd9Sstevel@tonic-gate } constname_t;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate /*
717c478bd9Sstevel@tonic-gate  * Structure for mapping a bit to a name and a description.  Instances
727c478bd9Sstevel@tonic-gate  * of this datatype should always be arrays which decode bits in a
737c478bd9Sstevel@tonic-gate  * number, and the index into the array should contain the description
747c478bd9Sstevel@tonic-gate  * of a bit at position "index" in the number being decoded.  The list
757c478bd9Sstevel@tonic-gate  * must be terminated by an entry with a NULL `bit_name'.
767c478bd9Sstevel@tonic-gate  */
777c478bd9Sstevel@tonic-gate typedef struct {
787c478bd9Sstevel@tonic-gate 	const char *bit_name;	/* name of bit */
797c478bd9Sstevel@tonic-gate 	const char *bit_descr;	/* description of bit's purpose */
807c478bd9Sstevel@tonic-gate } bitname_t;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate  * Note: These should be defined in upside down order to their
847c478bd9Sstevel@tonic-gate  * definitions in nca.h
857c478bd9Sstevel@tonic-gate  * (Assumes that current ordering convention in nca.h will
867c478bd9Sstevel@tonic-gate  * prevail for future additions)
877c478bd9Sstevel@tonic-gate  */
887c478bd9Sstevel@tonic-gate static const bitname_t node_refs[] = {
897c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000001" },
907c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000002" },
917c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000004" },
927c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000008" },
937c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000010" },
947c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000020" },
957c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000040" },
967c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000080" },
977c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000100" },
987c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000200" },
997c478bd9Sstevel@tonic-gate 	{ "REF_UNUSED",		"0x00000400" },
1007c478bd9Sstevel@tonic-gate 	{ "REF_SEGMAP",		"segmapped (PHYS|VIRT)" },
1017c478bd9Sstevel@tonic-gate 	{ "REF_NCAFS",		"NCAfs required" },
1027c478bd9Sstevel@tonic-gate 	{ "REF_VNODE",		"vnode hashed" },
1037c478bd9Sstevel@tonic-gate 	{ "REF_ERROR",		"errored" },
1047c478bd9Sstevel@tonic-gate 	{ "REF_OWNED",		"owned (won't be freed)" },
1057c478bd9Sstevel@tonic-gate 	{ "REF_UPCALL",		"upcall not completed yet" },
1067c478bd9Sstevel@tonic-gate 	{ "REF_CTAG",		"CTAG hashed" },
1077c478bd9Sstevel@tonic-gate 	{ "REF_PREEMPT",	"processing preempted" },
1087c478bd9Sstevel@tonic-gate 	{ "REF_ONVLRU",		"on virtual memory LRU list" },
1097c478bd9Sstevel@tonic-gate 	{ "REF_ONPLRU",		"on physical memory LRU list" },
1107c478bd9Sstevel@tonic-gate 	{ "REF_MISS",		"in miss processing" },
1117c478bd9Sstevel@tonic-gate 	{ "REF_NOLRU",		"not safe for LRU reclaim" },
1127c478bd9Sstevel@tonic-gate 	{ "REF_RESP",		"done parsing response header" },
1137c478bd9Sstevel@tonic-gate 	{ "REF_FILE",		"reachable through filename hash" },
1147c478bd9Sstevel@tonic-gate 	{ "REF_SAFED",		"not safe for use" },
1157c478bd9Sstevel@tonic-gate 	{ "REF_DONE",		"done with miss processing" },
1167c478bd9Sstevel@tonic-gate 	{ "REF_KMEM",		"content-backed via kmem_alloc()" },
1177c478bd9Sstevel@tonic-gate 	{ "REF_CKSUM",		"checksum mapping in-use" },
1187c478bd9Sstevel@tonic-gate 	{ "REF_VIRT",		"virtually mapped (data valid)" },
1197c478bd9Sstevel@tonic-gate 	{ "REF_PHYS",		"physically mapped (pp valid)" },
1207c478bd9Sstevel@tonic-gate 	{ "REF_URI",		"reachable through URI hash" },
1217c478bd9Sstevel@tonic-gate 	{ NULL }
1227c478bd9Sstevel@tonic-gate };
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate static const bitname_t advise_types[] = {
1257c478bd9Sstevel@tonic-gate 	{ "ADVISE",		"" },
1267c478bd9Sstevel@tonic-gate 	{ "ADVISE_REPLACE",	"replace cached object with provided object" },
1277c478bd9Sstevel@tonic-gate 	{ "ADVISE_FLUSH",	"flush cached object" },
1287c478bd9Sstevel@tonic-gate 	{ "ADVISE_TEMP",	"return this object; keep cached object" },
1297c478bd9Sstevel@tonic-gate 	{ NULL }
1307c478bd9Sstevel@tonic-gate };
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate  * Print `len' bytes of buffer `buf'.  Handle nonprintable characters
1347c478bd9Sstevel@tonic-gate  * specially.
1357c478bd9Sstevel@tonic-gate  */
1367c478bd9Sstevel@tonic-gate static void
1377c478bd9Sstevel@tonic-gate printbuf(uint8_t *buf, size_t len)
1387c478bd9Sstevel@tonic-gate {
1397c478bd9Sstevel@tonic-gate 	size_t	i;
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	/*
1427c478bd9Sstevel@tonic-gate 	 * TODO: display octal form of unprintable characters in dim mode
1437c478bd9Sstevel@tonic-gate 	 *	 once mdb pager bug is fixed.
1447c478bd9Sstevel@tonic-gate 	 */
1457c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++)
1467c478bd9Sstevel@tonic-gate 		mdb_printf(isgraph(buf[i]) ? "%c" : "\\%#o", buf[i]);
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
1497c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate /*
1527c478bd9Sstevel@tonic-gate  * Convert HTTP method operation `method' to a name.
1537c478bd9Sstevel@tonic-gate  */
1547c478bd9Sstevel@tonic-gate static const char *
1557c478bd9Sstevel@tonic-gate method2name(unsigned int method)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate 	unsigned int i;
1587c478bd9Sstevel@tonic-gate 	static constname_t http_methods[] = {
1597c478bd9Sstevel@tonic-gate 		{ "NCA_UNKNOWN", NCA_UNKNOWN	},
1607c478bd9Sstevel@tonic-gate 		{ "NCA_OPTIONS", NCA_OPTIONS	},
1617c478bd9Sstevel@tonic-gate 		{ "NCA_GET",	 NCA_GET	},
1627c478bd9Sstevel@tonic-gate 		{ "NCA_HEAD",	 NCA_HEAD	},
1637c478bd9Sstevel@tonic-gate 		{ "NCA_POST",	 NCA_POST	},
1647c478bd9Sstevel@tonic-gate 		{ "NCA_PUT",	 NCA_PUT	},
1657c478bd9Sstevel@tonic-gate 		{ "NCA_DELETE",  NCA_DELETE	},
1667c478bd9Sstevel@tonic-gate 		{ "NCA_TRACE",	 NCA_TRACE	},
1677c478bd9Sstevel@tonic-gate 		{ "NCA_RAW",	 NCA_RAW	},
1687c478bd9Sstevel@tonic-gate 		{ NULL }
1697c478bd9Sstevel@tonic-gate 	};
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	for (i = 0; http_methods[i].const_name != NULL; i++) {
1727c478bd9Sstevel@tonic-gate 		if (method == http_methods[i].const_value)
1737c478bd9Sstevel@tonic-gate 			return (http_methods[i].const_name);
1747c478bd9Sstevel@tonic-gate 	}
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	return ("<unknown>");
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate /*
1807c478bd9Sstevel@tonic-gate  * Convert TCP state `state' to a name.
1817c478bd9Sstevel@tonic-gate  */
1827c478bd9Sstevel@tonic-gate static const char *
1837c478bd9Sstevel@tonic-gate state2name(int state)
1847c478bd9Sstevel@tonic-gate {
1857c478bd9Sstevel@tonic-gate 	unsigned int i;
1867c478bd9Sstevel@tonic-gate 	static constname_t tcp_states[] = {
1877c478bd9Sstevel@tonic-gate 		{ "CLOSED",	 TCPS_CLOSED		},
1887c478bd9Sstevel@tonic-gate 		{ "IDLE",	 TCPS_IDLE		},
1897c478bd9Sstevel@tonic-gate 		{ "BOUND",	 TCPS_BOUND		},
1907c478bd9Sstevel@tonic-gate 		{ "LISTEN",	 TCPS_LISTEN		},
1917c478bd9Sstevel@tonic-gate 		{ "SYN_SENT",	 TCPS_SYN_SENT		},
1927c478bd9Sstevel@tonic-gate 		{ "SYN_RCVD",	 TCPS_SYN_RCVD		},
1937c478bd9Sstevel@tonic-gate 		{ "ESTABLISHED", TCPS_ESTABLISHED 	},
1947c478bd9Sstevel@tonic-gate 		{ "CLOSE_WAIT",	 TCPS_CLOSE_WAIT	},
1957c478bd9Sstevel@tonic-gate 		{ "FIN_WAIT1",	 TCPS_FIN_WAIT_1	},
1967c478bd9Sstevel@tonic-gate 		{ "FIN_WAIT2",	 TCPS_FIN_WAIT_2	},
1977c478bd9Sstevel@tonic-gate 		{ "CLOSING",	 TCPS_CLOSING		},
1987c478bd9Sstevel@tonic-gate 		{ "LAST_ACK",	 TCPS_LAST_ACK 		},
1997c478bd9Sstevel@tonic-gate 		{ "TIME_WAIT",	 TCPS_TIME_WAIT		},
2007c478bd9Sstevel@tonic-gate 		{ NULL }
2017c478bd9Sstevel@tonic-gate 	};
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	for (i = 0; tcp_states[i].const_name != NULL; i++) {
2047c478bd9Sstevel@tonic-gate 		if (state == tcp_states[i].const_value)
2057c478bd9Sstevel@tonic-gate 			return (tcp_states[i].const_name);
2067c478bd9Sstevel@tonic-gate 	}
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	return ("<unknown>");
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate /*
2127c478bd9Sstevel@tonic-gate  * Convert an nca_io2_t direct_type into a name.
2137c478bd9Sstevel@tonic-gate  */
2147c478bd9Sstevel@tonic-gate static const char *
2157c478bd9Sstevel@tonic-gate direct2name(unsigned int type)
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate 	unsigned int i;
2187c478bd9Sstevel@tonic-gate 	static const constname_t direct_types[] = {
2197c478bd9Sstevel@tonic-gate 		{ "DIRECT_NONE",	NCA_IO_DIRECT_NONE	},
2207c478bd9Sstevel@tonic-gate 		{ "DIRECT_FILENAME",	NCA_IO_DIRECT_FILENAME	},
2217c478bd9Sstevel@tonic-gate 		{ "DIRECT_SHMSEG",	NCA_IO_DIRECT_SHMSEG	},
2227c478bd9Sstevel@tonic-gate 		{ "DIRECT_FILEDESC",	NCA_IO_DIRECT_FILEDESC	},
2237c478bd9Sstevel@tonic-gate 		{ "DIRECT_CTAG",	NCA_IO_DIRECT_CTAG	},
2247c478bd9Sstevel@tonic-gate 		{ "DIRECT_SPLICE",	NCA_IO_DIRECT_SPLICE	},
2257c478bd9Sstevel@tonic-gate 		{ "DIRECT_TEE",		NCA_IO_DIRECT_TEE 	},
2267c478bd9Sstevel@tonic-gate 		{ "DIRECT_FILE_FD",	NCA_IO_DIRECT_FILE_FD 	},
2277c478bd9Sstevel@tonic-gate 		{ NULL,			0			}
2287c478bd9Sstevel@tonic-gate 	};
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	for (i = 0; direct_types[i].const_name != NULL; i++) {
2317c478bd9Sstevel@tonic-gate 		if (type == direct_types[i].const_value)
2327c478bd9Sstevel@tonic-gate 			return (direct_types[i].const_name);
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	return ("<unknown>");
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate /*
2397c478bd9Sstevel@tonic-gate  * Convert an nca_io2_t operation into a name.
2407c478bd9Sstevel@tonic-gate  */
2417c478bd9Sstevel@tonic-gate static const char *
2427c478bd9Sstevel@tonic-gate op2name(nca_op_t op)
2437c478bd9Sstevel@tonic-gate {
2447c478bd9Sstevel@tonic-gate 	unsigned int i;
2457c478bd9Sstevel@tonic-gate 	static const constname_t op_types[] = {
2467c478bd9Sstevel@tonic-gate 		{ "http",		http_op		},
2477c478bd9Sstevel@tonic-gate 		{ "error",		error_op	},
2487c478bd9Sstevel@tonic-gate 		{ "error_retry",	error_retry_op	},
2497c478bd9Sstevel@tonic-gate 		{ "resource",		resource_op	},
2507c478bd9Sstevel@tonic-gate 		{ "timeout",		timeout_op	},
2517c478bd9Sstevel@tonic-gate 		{ "door_attach",	door_attach_op	},
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 		{ "log",		log_op		},
2547c478bd9Sstevel@tonic-gate 		{ "log_ok",		log_ok_op	},
2557c478bd9Sstevel@tonic-gate 		{ "log_error",		log_error_op	},
2567c478bd9Sstevel@tonic-gate 		{ "log_op_fiov",	log_op_fiov	},
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 		{ NULL,			0		}
2597c478bd9Sstevel@tonic-gate 	};
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	for (i = 0; op_types[i].const_name != NULL; i++) {
2627c478bd9Sstevel@tonic-gate 		if (op == op_types[i].const_value)
2637c478bd9Sstevel@tonic-gate 			return (op_types[i].const_name);
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	return ("<unknown>");
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate /*
2707c478bd9Sstevel@tonic-gate  * Convert from ticks to milliseconds.
2717c478bd9Sstevel@tonic-gate  */
2727c478bd9Sstevel@tonic-gate static uint64_t
2737c478bd9Sstevel@tonic-gate tick2msec(uint64_t tick)
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate 	static int tick_per_msec;
2767c478bd9Sstevel@tonic-gate 	static int msec_per_tick;
2777c478bd9Sstevel@tonic-gate 	static int once;
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	if (once == 0) {
2807c478bd9Sstevel@tonic-gate 		if (mdb_readvar(&tick_per_msec, "tick_per_msec") == -1) {
2817c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read symbol tick_per_msec");
2827c478bd9Sstevel@tonic-gate 			return (0);
2837c478bd9Sstevel@tonic-gate 		}
2847c478bd9Sstevel@tonic-gate 		if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) {
2857c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read symbol msec_per_tick");
2867c478bd9Sstevel@tonic-gate 			return (0);
2877c478bd9Sstevel@tonic-gate 		}
2887c478bd9Sstevel@tonic-gate 		once++;
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	return (tick_per_msec ? tick / tick_per_msec : tick * msec_per_tick);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate /*
2957c478bd9Sstevel@tonic-gate  * Print the core fields in an nca_io2_t.  With the "-v" argument,
2967c478bd9Sstevel@tonic-gate  * provide more verbose output.  With the "-p" argument, print payload
2977c478bd9Sstevel@tonic-gate  * information.
2987c478bd9Sstevel@tonic-gate  */
2997c478bd9Sstevel@tonic-gate static int
3007c478bd9Sstevel@tonic-gate nca_io2(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3017c478bd9Sstevel@tonic-gate {
3027c478bd9Sstevel@tonic-gate 	unsigned int	i;
3037c478bd9Sstevel@tonic-gate 	unsigned int	payload_len;
3047c478bd9Sstevel@tonic-gate 	uint64_t	payload_output_max = 0;
3057c478bd9Sstevel@tonic-gate 	unsigned int	verbose = FALSE;
3067c478bd9Sstevel@tonic-gate 	const int	IO2_ADVDELT = NCA_ADDR_WIDTH + 1;
3077c478bd9Sstevel@tonic-gate 	boolean_t	arm;
3087c478bd9Sstevel@tonic-gate 	nca_io2_t	io2;
3097c478bd9Sstevel@tonic-gate 	uint8_t		*buf;
3107c478bd9Sstevel@tonic-gate 	namedmem_t	area[3];
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
3137c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose,
3167c478bd9Sstevel@tonic-gate 	    'p', MDB_OPT_UINT64, &payload_output_max, NULL) != argc)
3177c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	if (!DCMD_HDRSPEC(flags) && verbose)
3207c478bd9Sstevel@tonic-gate 		mdb_printf("\n\n");
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags) || verbose) {
3237c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-*s %2s %4s %8s %*s %8s %16s %-12s%</u>\n",
3247c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "ADDR", "AV", "MFNP", "TID",
3257c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "CONN", "CONN_TAG", "CACHE_TAG",
3267c478bd9Sstevel@tonic-gate 		    "OPERATION");
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	if (mdb_vread(&io2, sizeof (nca_io2_t), addr) == -1) {
3307c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nca_io2_t at %p", addr);
3317c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
3327c478bd9Sstevel@tonic-gate 	}
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	if (io2.version != NCA_HTTP_VERSION2)
3357c478bd9Sstevel@tonic-gate 		mdb_warn("nca_io2_t at %p has incorrect version `%u'\n", addr,
3367c478bd9Sstevel@tonic-gate 		    io2.version);
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	mdb_printf("%0*p %02x %c%c%c%c %08x %0*llx %08x %016llx %s\n",
3397c478bd9Sstevel@tonic-gate 	    NCA_ADDR_WIDTH, addr, io2.advisory, YESNO(io2.more),
3407c478bd9Sstevel@tonic-gate 	    YESNO(io2.first), YESNO(io2.nocache), YESNO(io2.preempt),
3417c478bd9Sstevel@tonic-gate 	    (uint32_t)io2.tid, NCA_ADDR_WIDTH, io2.cid, io2.tag, io2.ctag,
3427c478bd9Sstevel@tonic-gate 	    op2name(io2.op));
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	if (verbose) {
3457c478bd9Sstevel@tonic-gate 		arm = B_TRUE;
3467c478bd9Sstevel@tonic-gate 		for (i = 0; advise_types[i].bit_name != NULL; i++) {
3477c478bd9Sstevel@tonic-gate 			if ((io2.advisory & (1 << i)) == 0)
3487c478bd9Sstevel@tonic-gate 				continue;
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 			if (arm) {
3517c478bd9Sstevel@tonic-gate 				mdb_printf("%*s|\n", IO2_ADVDELT, "");
3527c478bd9Sstevel@tonic-gate 				mdb_printf("%*s+-->  ", IO2_ADVDELT, "");
3537c478bd9Sstevel@tonic-gate 				arm = B_FALSE;
3547c478bd9Sstevel@tonic-gate 			} else
3557c478bd9Sstevel@tonic-gate 				mdb_printf("%*s      ", IO2_ADVDELT, "");
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 			mdb_printf("%-15s %s\n", advise_types[i].bit_name,
3587c478bd9Sstevel@tonic-gate 			    advise_types[i].bit_descr);
3597c478bd9Sstevel@tonic-gate 		}
3607c478bd9Sstevel@tonic-gate 	}
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	payload_len = io2.data_len + io2.direct_len + io2.trailer_len;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	if (payload_output_max == 0 || payload_len == 0)
3657c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	mdb_inc_indent(4);
3687c478bd9Sstevel@tonic-gate 	mdb_printf("\n%u byte payload consists of:\n", payload_len);
3697c478bd9Sstevel@tonic-gate 	mdb_inc_indent(4);
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	buf = mdb_alloc(payload_output_max, UM_SLEEP);
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate 	area[0].nm_name = "data";
3747c478bd9Sstevel@tonic-gate 	area[0].nm_addr = addr + io2.data;
3757c478bd9Sstevel@tonic-gate 	area[0].nm_len  = io2.data_len;
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 	area[1].nm_name = direct2name(io2.direct_type);
3787c478bd9Sstevel@tonic-gate 	area[1].nm_addr = addr + io2.direct;
3797c478bd9Sstevel@tonic-gate 	area[1].nm_len  = io2.direct_len;
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	area[2].nm_name = "trailer";
3827c478bd9Sstevel@tonic-gate 	area[2].nm_addr = addr + io2.trailer;
3837c478bd9Sstevel@tonic-gate 	area[2].nm_len  = io2.trailer_len;
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 	for (i = 0; i < sizeof (area) / sizeof (area[0]); i++) {
3867c478bd9Sstevel@tonic-gate 		if (area[i].nm_len <= 0)
3877c478bd9Sstevel@tonic-gate 			continue;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 		mdb_printf("%d byte %s area at %p (", area[i].nm_len,
3907c478bd9Sstevel@tonic-gate 		    area[i].nm_name, area[i].nm_addr);
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 		if (area[i].nm_len > payload_output_max) {
3937c478bd9Sstevel@tonic-gate 			mdb_printf("first");
3947c478bd9Sstevel@tonic-gate 			area[i].nm_len = (int)payload_output_max;
3957c478bd9Sstevel@tonic-gate 		} else
3967c478bd9Sstevel@tonic-gate 			mdb_printf("all");
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 		mdb_printf(" %u bytes follow):\n", area[i].nm_len);
3997c478bd9Sstevel@tonic-gate 		if (mdb_vread(buf, area[i].nm_len, area[i].nm_addr) == -1)
4007c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read %s area at %p", area[i].nm_name,
4017c478bd9Sstevel@tonic-gate 			    area[i].nm_addr);
4027c478bd9Sstevel@tonic-gate 		else {
4037c478bd9Sstevel@tonic-gate 			mdb_inc_indent(4);
4047c478bd9Sstevel@tonic-gate 			printbuf(buf, area[i].nm_len);
4057c478bd9Sstevel@tonic-gate 			mdb_dec_indent(4);
4067c478bd9Sstevel@tonic-gate 		}
4077c478bd9Sstevel@tonic-gate 	}
4087c478bd9Sstevel@tonic-gate 	mdb_dec_indent(4);
4097c478bd9Sstevel@tonic-gate 	mdb_dec_indent(4);
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	mdb_free(buf, payload_output_max);
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate static void
4177c478bd9Sstevel@tonic-gate nca_io2_help(void)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate 	mdb_printf("Print the core information for a given NCA nca_io2_t.\n");
4207c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
4217c478bd9Sstevel@tonic-gate 	mdb_printf("\t-p N\tshow up to N bytes of payload information from\n");
4227c478bd9Sstevel@tonic-gate 	mdb_printf("\t\teach payload area\n");
4237c478bd9Sstevel@tonic-gate 	mdb_printf("\t\t(reminder: default radix is %<b>hex%</b>)\n");
4247c478bd9Sstevel@tonic-gate 	mdb_printf("\t-v\tbe verbose (more descriptive)\n");
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate /*
4287c478bd9Sstevel@tonic-gate  * Print the core fields for one or all NCA timers.  If no address is
4297c478bd9Sstevel@tonic-gate  * specified, all NCA timers are printed; otherwise the specified timer
4307c478bd9Sstevel@tonic-gate  * list is printed.  With the "-e" argument, the "encapsulated" pointer
4317c478bd9Sstevel@tonic-gate  * for each te_t in a given tb_t is shown in parentheses.
4327c478bd9Sstevel@tonic-gate  */
4337c478bd9Sstevel@tonic-gate static int
4347c478bd9Sstevel@tonic-gate nca_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4357c478bd9Sstevel@tonic-gate {
4367c478bd9Sstevel@tonic-gate 	unsigned int	show_encap = FALSE;
4377c478bd9Sstevel@tonic-gate 	void		*tb_addr, *te_addr;
4387c478bd9Sstevel@tonic-gate 	clock_t		lbolt, first_exec = 0;
4397c478bd9Sstevel@tonic-gate 	ti_t		ti;
4407c478bd9Sstevel@tonic-gate 	tb_t		tb;
4417c478bd9Sstevel@tonic-gate 	te_t		te;
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
4447c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("nca_timer", "nca_timer", argc, argv) == -1) {
4457c478bd9Sstevel@tonic-gate 			mdb_warn("cannot walk timer list");
4467c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
4477c478bd9Sstevel@tonic-gate 		}
4487c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'e', MDB_OPT_SETBITS, TRUE, &show_encap,
4527c478bd9Sstevel@tonic-gate 	    NULL) != argc)
4537c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
4567c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-*s %-*s %-55s%</u>\n", NCA_ADDR_WIDTH, "TI",
4577c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "SQUEUE", "FIRELIST +MSEC");
4587c478bd9Sstevel@tonic-gate 	}
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ti, sizeof (ti_t), addr) == -1) {
4617c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read ti_t at %p", addr);
4627c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4637c478bd9Sstevel@tonic-gate 	}
4647c478bd9Sstevel@tonic-gate 
465*d3d50737SRafael Vanoni 	if ((lbolt = (clock_t)mdb_get_lbolt()) == -1)
4667c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate 	mdb_printf("%0*p %0*p", NCA_ADDR_WIDTH, addr, NCA_ADDR_WIDTH, ti.ep);
4697c478bd9Sstevel@tonic-gate 	mdb_inc_indent(24);
4707c478bd9Sstevel@tonic-gate 	for (tb_addr = ti.head; tb_addr != NULL; tb_addr = tb.next) {
4717c478bd9Sstevel@tonic-gate 		if (mdb_vread(&tb, sizeof (tb_t), (uintptr_t)tb_addr) == -1) {
4727c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read tb_t at %p", tb_addr);
4737c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
4747c478bd9Sstevel@tonic-gate 		}
4757c478bd9Sstevel@tonic-gate 		if (first_exec == 0) {
4767c478bd9Sstevel@tonic-gate 			mdb_printf(" %ld", tick2msec(tb.exec - lbolt));
4777c478bd9Sstevel@tonic-gate 			first_exec = tb.exec;
4787c478bd9Sstevel@tonic-gate 		} else
4797c478bd9Sstevel@tonic-gate 			mdb_printf(" %+lld", tick2msec(tb.exec - first_exec));
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 		if (!show_encap || tb.head == NULL)
4827c478bd9Sstevel@tonic-gate 			continue;
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 		mdb_printf("(");
4857c478bd9Sstevel@tonic-gate 		for (te_addr = tb.head; te_addr != NULL; te_addr = te.next) {
4867c478bd9Sstevel@tonic-gate 			if (mdb_vread(&te, sizeof (te_t), (uintptr_t)te_addr)
4877c478bd9Sstevel@tonic-gate 			    == -1) {
4887c478bd9Sstevel@tonic-gate 				mdb_warn("cannot read te_t at %p", te_addr);
4897c478bd9Sstevel@tonic-gate 				return (DCMD_ERR);
4907c478bd9Sstevel@tonic-gate 			}
4917c478bd9Sstevel@tonic-gate 			mdb_printf("%0p%s", te.ep, te.next == NULL ? "" : " ");
4927c478bd9Sstevel@tonic-gate 		}
4937c478bd9Sstevel@tonic-gate 		mdb_printf(")");
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4967c478bd9Sstevel@tonic-gate 	mdb_dec_indent(24);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate static void
5027c478bd9Sstevel@tonic-gate nca_timer_help(void)
5037c478bd9Sstevel@tonic-gate {
5047c478bd9Sstevel@tonic-gate 	mdb_printf("Print the core information for one or all NCA timer\n");
5057c478bd9Sstevel@tonic-gate 	mdb_printf("lists.  If no timer list is given, then all timer lists\n");
5067c478bd9Sstevel@tonic-gate 	mdb_printf("are shown.  For each timer list, the list of timers to\n");
5077c478bd9Sstevel@tonic-gate 	mdb_printf("fire on that list are shown, the first in absolute\n");
5087c478bd9Sstevel@tonic-gate 	mdb_printf("ticks and the rest in ticks relative to the first.\n\n");
5097c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
5107c478bd9Sstevel@tonic-gate 	mdb_printf("\t-e\tshow the encapsulating pointer for each event ");
5117c478bd9Sstevel@tonic-gate 	mdb_printf("at each fire time\n");
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate /*
5157c478bd9Sstevel@tonic-gate  * Print the core fields in an NCA node_t.  With the "-r" argument,
5167c478bd9Sstevel@tonic-gate  * provide additional information about the request; with "-v",
5177c478bd9Sstevel@tonic-gate  * provide more verbose output.
5187c478bd9Sstevel@tonic-gate  */
5197c478bd9Sstevel@tonic-gate static int
5207c478bd9Sstevel@tonic-gate nca_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5217c478bd9Sstevel@tonic-gate {
5227c478bd9Sstevel@tonic-gate 	unsigned int	i, max;
5237c478bd9Sstevel@tonic-gate 	unsigned int	verbose = FALSE;
5247c478bd9Sstevel@tonic-gate 	unsigned int	request = FALSE;
5257c478bd9Sstevel@tonic-gate 	const int	NODE_REFDELT = NCA_ADDR_WIDTH + 4 + 2;
5267c478bd9Sstevel@tonic-gate 	boolean_t	arm;
5277c478bd9Sstevel@tonic-gate 	node_t		node;
5287c478bd9Sstevel@tonic-gate 	char		*buf;
5297c478bd9Sstevel@tonic-gate 	namedmem_t	hdr[4];
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
5327c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose,
5357c478bd9Sstevel@tonic-gate 	    'r', MDB_OPT_SETBITS, TRUE, &request, 'p', NULL) != argc)
5367c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	if (!DCMD_HDRSPEC(flags) && verbose)
5397c478bd9Sstevel@tonic-gate 		mdb_printf("\n\n");
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags) || verbose) {
5427c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-*s %4s %5s %8s %-*s %-*s %-*s %-*s%</u>\n",
5437c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "ADDR", "REF", "STATE", "DATASIZE",
5447c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "SQUEUE", NCA_ADDR_WIDTH, "REQUEST",
5457c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "PLRUN", NCA_ADDR_WIDTH, "VLRUN");
5467c478bd9Sstevel@tonic-gate 	}
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	if (mdb_vread(&node, sizeof (node_t), addr) == -1) {
5497c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read node_t at %p", addr);
5507c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5517c478bd9Sstevel@tonic-gate 	}
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	mdb_printf("%0*p %4d %05x %8d %0*p %0*p %0*p %0*p\n",
5547c478bd9Sstevel@tonic-gate 	    NCA_ADDR_WIDTH, addr, node.cnt, node.ref,
5557c478bd9Sstevel@tonic-gate 	    node.datasz, NCA_ADDR_WIDTH, node.sqp, NCA_ADDR_WIDTH,
5567c478bd9Sstevel@tonic-gate 	    node.req, NCA_ADDR_WIDTH, node.plrunn, NCA_ADDR_WIDTH, node.vlrunn);
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	if (verbose) {
5597c478bd9Sstevel@tonic-gate 		arm = B_TRUE;
5607c478bd9Sstevel@tonic-gate 		for (i = 0; node_refs[i].bit_name != NULL; i++) {
5617c478bd9Sstevel@tonic-gate 			if ((node.ref & (1 << i)) == 0)
5627c478bd9Sstevel@tonic-gate 				continue;
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 			if (arm) {
5657c478bd9Sstevel@tonic-gate 				mdb_printf("%*s|\n", NODE_REFDELT, "");
5667c478bd9Sstevel@tonic-gate 				mdb_printf("%*s+-->  ", NODE_REFDELT, "");
5677c478bd9Sstevel@tonic-gate 				arm = B_FALSE;
5687c478bd9Sstevel@tonic-gate 			} else
5697c478bd9Sstevel@tonic-gate 				mdb_printf("%*s      ", NODE_REFDELT, "");
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 			mdb_printf("%-12s %s\n", node_refs[i].bit_name,
5727c478bd9Sstevel@tonic-gate 			    node_refs[i].bit_descr);
5737c478bd9Sstevel@tonic-gate 		}
5747c478bd9Sstevel@tonic-gate 	}
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	if (!request || node.req == NULL)
5777c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	mdb_inc_indent(4);
5807c478bd9Sstevel@tonic-gate 	mdb_printf("\n%u byte HTTP/%u.%u %s request (%u bytes in header, "
5817c478bd9Sstevel@tonic-gate 	    "%u in content)\n", node.reqsz, node.version >> 16,
5827c478bd9Sstevel@tonic-gate 	    node.version & 0xff, method2name(node.method), node.reqhdrsz,
5837c478bd9Sstevel@tonic-gate 	    node.reqcontl);
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 	hdr[0].nm_name = "URI";
5867c478bd9Sstevel@tonic-gate 	hdr[0].nm_addr = (uintptr_t)node.path;
5877c478bd9Sstevel@tonic-gate 	hdr[0].nm_len  = node.pathsz;
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate 	hdr[1].nm_name = "Accept";
5907c478bd9Sstevel@tonic-gate 	hdr[1].nm_addr = (uintptr_t)node.reqaccept;
5917c478bd9Sstevel@tonic-gate 	hdr[1].nm_len  = node.reqacceptsz;
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate 	hdr[2].nm_name = "Accept-Language";
5947c478bd9Sstevel@tonic-gate 	hdr[2].nm_addr = (uintptr_t)node.reqacceptl;
5957c478bd9Sstevel@tonic-gate 	hdr[2].nm_len  = node.reqacceptlsz;
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	hdr[3].nm_name = "Host";
5987c478bd9Sstevel@tonic-gate 	hdr[3].nm_addr = (uintptr_t)node.reqhost;
5997c478bd9Sstevel@tonic-gate 	hdr[3].nm_len  = node.reqhostsz;
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	/*
6027c478bd9Sstevel@tonic-gate 	 * A little optimization.  Allocate all of the necessary memory here,
6037c478bd9Sstevel@tonic-gate 	 * so we don't have to allocate on each loop iteration.
6047c478bd9Sstevel@tonic-gate 	 */
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	max = node.reqhdrsz;
6077c478bd9Sstevel@tonic-gate 	for (i = 0; i < 4; i++)
6087c478bd9Sstevel@tonic-gate 		max = MAX(max, hdr[i].nm_len);
6097c478bd9Sstevel@tonic-gate 	max++;
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	buf = mdb_alloc(max, UM_SLEEP);
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate 	mdb_inc_indent(4);
6147c478bd9Sstevel@tonic-gate 	for (i = 0; i < sizeof (hdr) / sizeof (hdr[0]); i++) {
6157c478bd9Sstevel@tonic-gate 		if (hdr[i].nm_len <= 0)
6167c478bd9Sstevel@tonic-gate 			continue;
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 		if (mdb_vread(buf, hdr[i].nm_len, hdr[i].nm_addr) == -1) {
6197c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read \"%s\" header field at %p",
6207c478bd9Sstevel@tonic-gate 			    hdr[i].nm_name, hdr[i].nm_addr);
6217c478bd9Sstevel@tonic-gate 			continue;
6227c478bd9Sstevel@tonic-gate 		}
6237c478bd9Sstevel@tonic-gate 		buf[hdr[i].nm_len] = '\0';
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 		mdb_printf("%s: ", hdr[i].nm_name);
6267c478bd9Sstevel@tonic-gate 		mdb_inc_indent(4);
6277c478bd9Sstevel@tonic-gate 		mdb_printf("%s\n", buf);
6287c478bd9Sstevel@tonic-gate 		mdb_dec_indent(4);
6297c478bd9Sstevel@tonic-gate 	}
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	if (node.reqhdrsz > 0 && verbose) {
6327c478bd9Sstevel@tonic-gate 		if (mdb_vread(buf, node.reqhdrsz, (uintptr_t)node.reqhdr) == -1)
6337c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read header at %p", node.reqhdr);
6347c478bd9Sstevel@tonic-gate 		else {
6357c478bd9Sstevel@tonic-gate 			mdb_printf("Raw header: ");
6367c478bd9Sstevel@tonic-gate 			mdb_inc_indent(4);
6377c478bd9Sstevel@tonic-gate 			printbuf((uint8_t *)buf, node.reqhdrsz);
6387c478bd9Sstevel@tonic-gate 			mdb_dec_indent(4);
6397c478bd9Sstevel@tonic-gate 		}
6407c478bd9Sstevel@tonic-gate 	}
6417c478bd9Sstevel@tonic-gate 	mdb_dec_indent(4);
6427c478bd9Sstevel@tonic-gate 	mdb_dec_indent(4);
6437c478bd9Sstevel@tonic-gate 
6447c478bd9Sstevel@tonic-gate 	mdb_free(buf, max);
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
6477c478bd9Sstevel@tonic-gate }
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate static void
6507c478bd9Sstevel@tonic-gate nca_node_help(void)
6517c478bd9Sstevel@tonic-gate {
6527c478bd9Sstevel@tonic-gate 	mdb_printf("Print the core information for a given NCA node_t.\n\n");
6537c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
6547c478bd9Sstevel@tonic-gate 	mdb_printf("\t-r\tdisplay HTTP request information\n");
6557c478bd9Sstevel@tonic-gate 	mdb_printf("\t-v\tbe verbose (more descriptive)\n");
6567c478bd9Sstevel@tonic-gate }
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate /*
6597c478bd9Sstevel@tonic-gate  * Print the core fields in an NCA nca_conn_t.  With the "-t" argument, skip
6607c478bd9Sstevel@tonic-gate  * all nca_conn_t's that are in the TIME_WAIT state.  With the "-x" argument,
6617c478bd9Sstevel@tonic-gate  * show the xmit data.
6627c478bd9Sstevel@tonic-gate  */
6637c478bd9Sstevel@tonic-gate static int
6647c478bd9Sstevel@tonic-gate nca_conn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6657c478bd9Sstevel@tonic-gate {
6667c478bd9Sstevel@tonic-gate 	unsigned int	i;
6677c478bd9Sstevel@tonic-gate 	nca_conn_t 		conn;
6687c478bd9Sstevel@tonic-gate 	unsigned int	show_timewait = TRUE;
6697c478bd9Sstevel@tonic-gate 	unsigned int	show_xmit = FALSE;
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
6727c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'x', MDB_OPT_SETBITS, TRUE, &show_xmit,
6757c478bd9Sstevel@tonic-gate 	    't', MDB_OPT_CLRBITS, TRUE, &show_timewait, NULL) != argc)
6767c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
6797c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-*s %3s %8s %15s %15s %-*s %-10s%</u>\n",
6807c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "ADDR", "REF", "CREATE", "LOCAL_ADDR",
6817c478bd9Sstevel@tonic-gate 		    "REMOTE_ADDR", NCA_ADDR_WIDTH,  "NODE", "STATE");
6827c478bd9Sstevel@tonic-gate 	}
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	if (mdb_vread(&conn, sizeof (nca_conn_t), addr) == -1) {
6857c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nca_conn_t at %p", addr);
6867c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6877c478bd9Sstevel@tonic-gate 	}
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 	if (!show_timewait && conn.tcp_state == TCPS_TIME_WAIT)
6907c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate 	mdb_printf("%0*p %3d %8lx %15I %15I %0*p %s\n", NCA_ADDR_WIDTH, addr,
6937c478bd9Sstevel@tonic-gate 	    conn.ref, conn.create, conn.laddr, conn.faddr, NCA_ADDR_WIDTH,
6947c478bd9Sstevel@tonic-gate 	    conn.req_np, state2name(conn.tcp_state));
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 	if (show_xmit) {
6977c478bd9Sstevel@tonic-gate 		mdb_inc_indent(4);
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 		for (i = 0; i < TCP_XMIT_MAX_IX; i++) {
7007c478bd9Sstevel@tonic-gate 			mdb_printf("xmit[%d]\n", i);
7017c478bd9Sstevel@tonic-gate 			mdb_printf("\tref pointer\t\t%p\n", conn.xmit[i].np);
7027c478bd9Sstevel@tonic-gate 			mdb_printf("\tdata pointer\t\t%p\n", conn.xmit[i].dp);
7037c478bd9Sstevel@tonic-gate 			mdb_printf("\tcksum array\t\t%p\n", conn.xmit[i].cp);
7047c478bd9Sstevel@tonic-gate 			mdb_printf("\tremaining xmit data\t%d\n",
7057c478bd9Sstevel@tonic-gate 			    conn.xmit[i].sz);
7067c478bd9Sstevel@tonic-gate 			mdb_printf("\tref to node_t\t\t%p\n",
7077c478bd9Sstevel@tonic-gate 			    conn.xmit[i].refed);
7087c478bd9Sstevel@tonic-gate 			mdb_printf("\tremaining segment data\t%d\n",
7097c478bd9Sstevel@tonic-gate 			    conn.xmit[i].dsz);
7107c478bd9Sstevel@tonic-gate 			mdb_printf("\tvirtual pointer\t\t%p\n",
7117c478bd9Sstevel@tonic-gate 			    conn.xmit[i].dvp);
7127c478bd9Sstevel@tonic-gate 		}
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 		mdb_dec_indent(4);
7157c478bd9Sstevel@tonic-gate 	}
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
7187c478bd9Sstevel@tonic-gate }
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate static void
7217c478bd9Sstevel@tonic-gate nca_conn_help(void)
7227c478bd9Sstevel@tonic-gate {
7237c478bd9Sstevel@tonic-gate 	mdb_printf("Print the core information for a given NCA "
7247c478bd9Sstevel@tonic-gate 	    "nca_conn_t.\n\n");
7257c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
7267c478bd9Sstevel@tonic-gate 	mdb_printf("\t-t\tskip connections in the TIME_WAIT state\n");
7277c478bd9Sstevel@tonic-gate 	mdb_printf("\t-x\tshow TCP XMIT information\n");
7287c478bd9Sstevel@tonic-gate }
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate /*
7317c478bd9Sstevel@tonic-gate  * Print the core TCP-related fields in an NCA nca_conn_t.  With the "-t"
7327c478bd9Sstevel@tonic-gate  * argument, skips all nca_conn_t's that are in the TIME_WAIT state.
7337c478bd9Sstevel@tonic-gate  */
7347c478bd9Sstevel@tonic-gate static int
7357c478bd9Sstevel@tonic-gate nca_tcpconn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7367c478bd9Sstevel@tonic-gate {
7377c478bd9Sstevel@tonic-gate 	nca_conn_t		conn;
7387c478bd9Sstevel@tonic-gate 	unsigned int	show_timewait = TRUE;
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
7417c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 't', MDB_OPT_CLRBITS, TRUE, &show_timewait,
7447c478bd9Sstevel@tonic-gate 	    NULL) != argc)
7457c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
7487c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-*s %21s %5s %8s %5s %8s %5s %-9s%</u>\n",
7497c478bd9Sstevel@tonic-gate 		    NCA_ADDR_WIDTH, "ADDR", "REMOTE_ADDR", "SWIND", "SUNASEQ",
7507c478bd9Sstevel@tonic-gate 		    "SNSEQ", "RACKSEQ", "RNSEQ", "STATE");
7517c478bd9Sstevel@tonic-gate 	}
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 	if (mdb_vread(&conn, sizeof (nca_conn_t), addr) == -1) {
7547c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nca_conn_t at %p", addr);
7557c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
7567c478bd9Sstevel@tonic-gate 	}
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 	if (!show_timewait && conn.tcp_state == TCPS_TIME_WAIT)
7597c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	mdb_nhconvert(&conn.conn_fport, &conn.conn_fport, sizeof (in_port_t));
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 	mdb_printf("%0*p %15I:%05hu %5u %08x %+5d %08x %+5d %-9s\n",
7647c478bd9Sstevel@tonic-gate 	    NCA_ADDR_WIDTH, addr, conn.faddr, conn.conn_fport, conn.tcp_swnd,
7657c478bd9Sstevel@tonic-gate 	    conn.tcp_suna, conn.tcp_snxt - conn.tcp_suna, conn.tcp_rack,
7667c478bd9Sstevel@tonic-gate 	    conn.tcp_rnxt - conn.tcp_rack, state2name(conn.tcp_state));
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
7697c478bd9Sstevel@tonic-gate }
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate static void
7727c478bd9Sstevel@tonic-gate nca_tcpconn_help(void)
7737c478bd9Sstevel@tonic-gate {
7747c478bd9Sstevel@tonic-gate 	mdb_printf("Print the core TCP-related information for a given ");
7757c478bd9Sstevel@tonic-gate 	mdb_printf("NCA nca_conn_t.\n\n");
7767c478bd9Sstevel@tonic-gate 	mdb_printf("Options:\n");
7777c478bd9Sstevel@tonic-gate 	mdb_printf("\t-t\tskip connections in the TIME_WAIT state\n");
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate /*
7817c478bd9Sstevel@tonic-gate  * Initialize a walk for the NCA connection fanout table.  Note that
7827c478bd9Sstevel@tonic-gate  * local walks are not supported since they're more trouble than
7837c478bd9Sstevel@tonic-gate  * they're worth.
7847c478bd9Sstevel@tonic-gate  */
7857c478bd9Sstevel@tonic-gate static int
7867c478bd9Sstevel@tonic-gate nca_connf_walk_init(mdb_walk_state_t *wsp)
7877c478bd9Sstevel@tonic-gate {
7887c478bd9Sstevel@tonic-gate 	int	fanout_size;
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0) {
7917c478bd9Sstevel@tonic-gate 		mdb_warn("nca_connf_walk does not support local walks\n");
7927c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
7937c478bd9Sstevel@tonic-gate 	}
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, "nca_conn_fanout") == -1) {
7967c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read symbol nca_conn_fanout");
7977c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
7987c478bd9Sstevel@tonic-gate 	}
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&fanout_size, "nca_conn_fanout_size") == -1) {
8017c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read symbol nca_conn_fanout_size");
8027c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8037c478bd9Sstevel@tonic-gate 	}
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)(uintptr_t)fanout_size;
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
8087c478bd9Sstevel@tonic-gate }
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate /*
8117c478bd9Sstevel@tonic-gate  * Walk the NCA connection fanout table; `wsp->walk_data' is used to keep
8127c478bd9Sstevel@tonic-gate  * track of the number of indicies that are left to walk so we know when
8137c478bd9Sstevel@tonic-gate  * to stop.
8147c478bd9Sstevel@tonic-gate  */
8157c478bd9Sstevel@tonic-gate static int
8167c478bd9Sstevel@tonic-gate nca_connf_walk_step(mdb_walk_state_t *wsp)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate 	connf_t		connf;
8197c478bd9Sstevel@tonic-gate 	nca_conn_t		conn;
8207c478bd9Sstevel@tonic-gate 	int		status;
8217c478bd9Sstevel@tonic-gate 	intptr_t	i = (intptr_t)wsp->walk_data;
8227c478bd9Sstevel@tonic-gate 
8237c478bd9Sstevel@tonic-gate 	if (i-- <= 0)
8247c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	if (mdb_vread(&connf, sizeof (connf_t), wsp->walk_addr) == -1) {
8277c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read connf_t at %p", wsp->walk_addr);
8287c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8297c478bd9Sstevel@tonic-gate 	}
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 	/*
8327c478bd9Sstevel@tonic-gate 	 * No point in walking the fanout if there are no
8337c478bd9Sstevel@tonic-gate 	 * connections in it.
8347c478bd9Sstevel@tonic-gate 	 */
8357c478bd9Sstevel@tonic-gate 	if (connf.head != NULL) {
8367c478bd9Sstevel@tonic-gate 		/*
8377c478bd9Sstevel@tonic-gate 		 * Point to the nca_conn_t instead of the connf_t so that output
8387c478bd9Sstevel@tonic-gate 		 * can be piped to ::nca_conn dcmd.
8397c478bd9Sstevel@tonic-gate 		 */
8407c478bd9Sstevel@tonic-gate 		if (mdb_vread(&conn, sizeof (nca_conn_t),
8417c478bd9Sstevel@tonic-gate 		    (uintptr_t)connf.head) == -1) {
8427c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read nca_conn_t at %p", connf.head);
8437c478bd9Sstevel@tonic-gate 			return (WALK_ERR);
8447c478bd9Sstevel@tonic-gate 		}
8457c478bd9Sstevel@tonic-gate 		status = wsp->walk_callback((uintptr_t)connf.head, &conn,
8467c478bd9Sstevel@tonic-gate 		    wsp->walk_cbdata);
8477c478bd9Sstevel@tonic-gate 	} else {
8487c478bd9Sstevel@tonic-gate 		status = WALK_NEXT;
8497c478bd9Sstevel@tonic-gate 	}
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)i;
8527c478bd9Sstevel@tonic-gate 	wsp->walk_addr += sizeof (connf_t);
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 	return (status);
8557c478bd9Sstevel@tonic-gate }
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate /*
8587c478bd9Sstevel@tonic-gate  * Initialize a walk for the NCA node fanout tables.  Note that local
8597c478bd9Sstevel@tonic-gate  * walks are not supported since they're more trouble than they're
8607c478bd9Sstevel@tonic-gate  * worth.
8617c478bd9Sstevel@tonic-gate  */
8627c478bd9Sstevel@tonic-gate static int
8637c478bd9Sstevel@tonic-gate nca_nodef_walk_init(mdb_walk_state_t *wsp)
8647c478bd9Sstevel@tonic-gate {
8657c478bd9Sstevel@tonic-gate 	char		varname[256];
8667c478bd9Sstevel@tonic-gate 	uint32_t	size;
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0) {
8697c478bd9Sstevel@tonic-gate 		mdb_warn("nca_nodef_walk does not support local walks\n");
8707c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
8717c478bd9Sstevel@tonic-gate 	}
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, wsp->walk_arg) == -1) {
8747c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read symbol %s", wsp->walk_arg);
8757c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8767c478bd9Sstevel@tonic-gate 	}
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	mdb_snprintf(varname, sizeof (varname), "%s_sz", wsp->walk_arg);
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&size, varname) == -1) {
8817c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read symbol %s", varname);
8827c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8837c478bd9Sstevel@tonic-gate 	}
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)(uintptr_t)size;
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
8887c478bd9Sstevel@tonic-gate }
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate /*
8917c478bd9Sstevel@tonic-gate  * Walk the NCA node fanout table; `wsp->walk_data' is used to keep
8927c478bd9Sstevel@tonic-gate  * track of the number of indicies that are left to walk so we know
8937c478bd9Sstevel@tonic-gate  * when to stop.
8947c478bd9Sstevel@tonic-gate  */
8957c478bd9Sstevel@tonic-gate static int
8967c478bd9Sstevel@tonic-gate nca_nodef_walk_step(mdb_walk_state_t *wsp)
8977c478bd9Sstevel@tonic-gate {
8987c478bd9Sstevel@tonic-gate 	nodef_t		nodef;
8997c478bd9Sstevel@tonic-gate 	node_t		node;
9007c478bd9Sstevel@tonic-gate 	int		status;
9017c478bd9Sstevel@tonic-gate 	intptr_t	i = (intptr_t)wsp->walk_data;
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate 	if (i-- <= 0)
9047c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 	if (mdb_vread(&nodef, sizeof (nodef_t), wsp->walk_addr) == -1) {
9077c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nodef_t at %p", wsp->walk_addr);
9087c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9097c478bd9Sstevel@tonic-gate 	}
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, &nodef, wsp->walk_cbdata);
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)i;
9147c478bd9Sstevel@tonic-gate 	wsp->walk_addr += sizeof (nodef_t);
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 	if (nodef.head != NULL) {
9177c478bd9Sstevel@tonic-gate 		/*
9187c478bd9Sstevel@tonic-gate 		 * Point to the node_t instead of the nodef_t so that output
9197c478bd9Sstevel@tonic-gate 		 * can be piped to ::nca_node dcmd.
9207c478bd9Sstevel@tonic-gate 		 */
9217c478bd9Sstevel@tonic-gate 		if (mdb_vread(&node, sizeof (node),
9227c478bd9Sstevel@tonic-gate 		    (uintptr_t)nodef.head) == -1) {
9237c478bd9Sstevel@tonic-gate 			mdb_warn("cannot read node_t at %p", nodef.head);
9247c478bd9Sstevel@tonic-gate 			return (WALK_ERR);
9257c478bd9Sstevel@tonic-gate 		}
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate 		status = wsp->walk_callback((uintptr_t)nodef.head,
9287c478bd9Sstevel@tonic-gate 		    &node, wsp->walk_cbdata);
9297c478bd9Sstevel@tonic-gate 	} else {
9307c478bd9Sstevel@tonic-gate 		status = WALK_NEXT;
9317c478bd9Sstevel@tonic-gate 	}
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 	return (status);
9347c478bd9Sstevel@tonic-gate }
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate /*
9377c478bd9Sstevel@tonic-gate  * Initialize a walk for the NCA CPU table.  Note that local walks
9387c478bd9Sstevel@tonic-gate  * are not supported since they're more trouble than they're worth.
9397c478bd9Sstevel@tonic-gate  */
9407c478bd9Sstevel@tonic-gate static int
9417c478bd9Sstevel@tonic-gate nca_cpu_walk_init(mdb_walk_state_t *wsp)
9427c478bd9Sstevel@tonic-gate {
9437c478bd9Sstevel@tonic-gate 	int	ncpus;
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0) {
9467c478bd9Sstevel@tonic-gate 		mdb_warn("nca_cpu_walk does not support local walks\n");
9477c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
9487c478bd9Sstevel@tonic-gate 	}
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, "nca_gv") == -1) {
9517c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read symbol nca_gv");
9527c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9537c478bd9Sstevel@tonic-gate 	}
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&ncpus, "ncpus") == -1) {
9567c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read symbol ncpus");
9577c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9587c478bd9Sstevel@tonic-gate 	}
9597c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)(uintptr_t)ncpus;
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
9627c478bd9Sstevel@tonic-gate }
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate /*
9657c478bd9Sstevel@tonic-gate  * Walk the NCA CPU table; `wsp->walk_data' is used to keep track of the
9667c478bd9Sstevel@tonic-gate  * number of CPUs that are left to walk so we know when to stop.
9677c478bd9Sstevel@tonic-gate  */
9687c478bd9Sstevel@tonic-gate static int
9697c478bd9Sstevel@tonic-gate nca_cpu_walk_step(mdb_walk_state_t *wsp)
9707c478bd9Sstevel@tonic-gate {
9717c478bd9Sstevel@tonic-gate 	nca_cpu_t	cpu;
9727c478bd9Sstevel@tonic-gate 	int		status;
9737c478bd9Sstevel@tonic-gate 	intptr_t	curcpu = (intptr_t)wsp->walk_data;
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate 	if (curcpu-- <= 0)
9767c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 	if (mdb_vread(&cpu, sizeof (nca_cpu_t), wsp->walk_addr) == -1) {
9797c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nca_cpu_t at %p", wsp->walk_addr);
9807c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9817c478bd9Sstevel@tonic-gate 	}
9827c478bd9Sstevel@tonic-gate 
9837c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, &cpu, wsp->walk_cbdata);
9847c478bd9Sstevel@tonic-gate 
9857c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)curcpu;
9867c478bd9Sstevel@tonic-gate 	wsp->walk_addr += sizeof (nca_cpu_t);
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 	return (status);
9897c478bd9Sstevel@tonic-gate }
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate /*
9927c478bd9Sstevel@tonic-gate  * Initialize a walk for the NCA timer list.  Note that local walks
9937c478bd9Sstevel@tonic-gate  * are not supported since this walk is layered on top of "nca_cpu"
9947c478bd9Sstevel@tonic-gate  * which doesn't support them (and they're not too useful here anyway).
9957c478bd9Sstevel@tonic-gate  */
9967c478bd9Sstevel@tonic-gate static int
9977c478bd9Sstevel@tonic-gate nca_timer_walk_init(mdb_walk_state_t *wsp)
9987c478bd9Sstevel@tonic-gate {
9997c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0) {
10007c478bd9Sstevel@tonic-gate 		mdb_warn("nca_timer_walk does not support local walks\n");
10017c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
10027c478bd9Sstevel@tonic-gate 	}
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 	if (mdb_layered_walk("nca_cpu", wsp) == -1) {
10057c478bd9Sstevel@tonic-gate 		mdb_warn("cannot walk nca_cpu");
10067c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10077c478bd9Sstevel@tonic-gate 	}
10087c478bd9Sstevel@tonic-gate 
10097c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
10107c478bd9Sstevel@tonic-gate }
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate /*
10137c478bd9Sstevel@tonic-gate  * Walk the NCA timer list; done as a layered walk on top of "nca_cpu".
10147c478bd9Sstevel@tonic-gate  */
10157c478bd9Sstevel@tonic-gate static int
10167c478bd9Sstevel@tonic-gate nca_timer_walk_step(mdb_walk_state_t *wsp)
10177c478bd9Sstevel@tonic-gate {
10187c478bd9Sstevel@tonic-gate 	const nca_cpu_t	*nca_cpu = wsp->walk_layer;
10197c478bd9Sstevel@tonic-gate 	ti_t		ti;
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 	/*
10227c478bd9Sstevel@tonic-gate 	 * Just skip CPUs that don't have any timers running.
10237c478bd9Sstevel@tonic-gate 	 */
10247c478bd9Sstevel@tonic-gate 	if (nca_cpu->tcp_ti == NULL)
10257c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ti, sizeof (ti_t), (uintptr_t)nca_cpu->tcp_ti) == -1) {
10287c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read ti_t at %p", nca_cpu->tcp_ti);
10297c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10307c478bd9Sstevel@tonic-gate 	}
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback((uintptr_t)nca_cpu->tcp_ti, &ti,
10337c478bd9Sstevel@tonic-gate 	    wsp->walk_cbdata));
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate /*
10377c478bd9Sstevel@tonic-gate  * Initialize a walk for NCA node LRUs; the type of LRU to walk should
10387c478bd9Sstevel@tonic-gate  * be specified through `wsp->walk_arg'.  If no starting location for
10397c478bd9Sstevel@tonic-gate  * the walk is given, `wsp->walk_addr' is set to the head of the
10407c478bd9Sstevel@tonic-gate  * appropriate LRU.
10417c478bd9Sstevel@tonic-gate  */
10427c478bd9Sstevel@tonic-gate static int
10437c478bd9Sstevel@tonic-gate nca_node_lru_walk_init(mdb_walk_state_t *wsp)
10447c478bd9Sstevel@tonic-gate {
10457c478bd9Sstevel@tonic-gate 	GElf_Sym	sym;
10467c478bd9Sstevel@tonic-gate 	lru_t		lru;
10477c478bd9Sstevel@tonic-gate 
10487c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0)
10497c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 	/*
10527c478bd9Sstevel@tonic-gate 	 * We do this instead of mdb_readvar() so that we catch changes
10537c478bd9Sstevel@tonic-gate 	 * in the size of the lru_t structure.
10547c478bd9Sstevel@tonic-gate 	 */
10557c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("nca_lru", &sym) == -1) {
10567c478bd9Sstevel@tonic-gate 		mdb_warn("cannot lookup symbol nca_lru");
10577c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10587c478bd9Sstevel@tonic-gate 	}
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	if (sym.st_size != sizeof (lru)) {
10617c478bd9Sstevel@tonic-gate 		mdb_warn("nca_lru object size mismatch\n");
10627c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10637c478bd9Sstevel@tonic-gate 	}
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	if (mdb_vread(&lru, sym.st_size, (uintptr_t)sym.st_value) == -1) {
10667c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nca_lru at %p", sym.st_value);
10677c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10687c478bd9Sstevel@tonic-gate 	}
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 	if (wsp->walk_arg == NCA_WALK_PLRU)
10717c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)lru.phead;
10727c478bd9Sstevel@tonic-gate 	else
10737c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)lru.vhead;
10747c478bd9Sstevel@tonic-gate 
10757c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
10767c478bd9Sstevel@tonic-gate }
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate /*
10797c478bd9Sstevel@tonic-gate  * Walk the NCA node LRUs; the type of LRU to walk should be specified
10807c478bd9Sstevel@tonic-gate  * through `wsp->walk_arg'.
10817c478bd9Sstevel@tonic-gate  */
10827c478bd9Sstevel@tonic-gate static int
10837c478bd9Sstevel@tonic-gate nca_node_lru_walk_step(mdb_walk_state_t *wsp)
10847c478bd9Sstevel@tonic-gate {
10857c478bd9Sstevel@tonic-gate 	node_t		node;
10867c478bd9Sstevel@tonic-gate 	int		status;
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr == 0)
10897c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 	if (mdb_vread(&node, sizeof (node_t), wsp->walk_addr) == -1) {
10927c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read node_t at %p", wsp->walk_addr);
10937c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10947c478bd9Sstevel@tonic-gate 	}
10957c478bd9Sstevel@tonic-gate 
10967c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, &node, wsp->walk_cbdata);
10977c478bd9Sstevel@tonic-gate 
10987c478bd9Sstevel@tonic-gate 	if (wsp->walk_arg == NCA_WALK_PLRU)
10997c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)node.plrunn;
11007c478bd9Sstevel@tonic-gate 	else
11017c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)node.vlrunn;
11027c478bd9Sstevel@tonic-gate 
11037c478bd9Sstevel@tonic-gate 	return (status);
11047c478bd9Sstevel@tonic-gate }
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate /*
11077c478bd9Sstevel@tonic-gate  * Walk the NCA node structures; follows node_t next pointers from a
11087c478bd9Sstevel@tonic-gate  * given offset, specified through `wsp->walk_arg'.
11097c478bd9Sstevel@tonic-gate  */
11107c478bd9Sstevel@tonic-gate static int
11117c478bd9Sstevel@tonic-gate nca_node_walk_step(mdb_walk_state_t *wsp)
11127c478bd9Sstevel@tonic-gate {
11137c478bd9Sstevel@tonic-gate 	node_t		node;
11147c478bd9Sstevel@tonic-gate 	int		status;
11157c478bd9Sstevel@tonic-gate 
11167c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr == 0) {
11177c478bd9Sstevel@tonic-gate 		mdb_warn("nca_node_walk does not support global walks\n");
11187c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
11197c478bd9Sstevel@tonic-gate 	}
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate 	if (mdb_vread(&node, sizeof (node_t), wsp->walk_addr) == -1) {
11227c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read node_t at %p", wsp->walk_addr);
11237c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
11247c478bd9Sstevel@tonic-gate 	}
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, &node, wsp->walk_cbdata);
11277c478bd9Sstevel@tonic-gate 	if (status != WALK_NEXT)
11287c478bd9Sstevel@tonic-gate 		return (status);
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 	/* LINTED */
11317c478bd9Sstevel@tonic-gate 	wsp->walk_addr = *(uintptr_t *)((caddr_t)&node +
11327c478bd9Sstevel@tonic-gate 	    (uint_t)(uintptr_t)wsp->walk_arg);
11337c478bd9Sstevel@tonic-gate 
11347c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr == 0)
11357c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
11387c478bd9Sstevel@tonic-gate }
11397c478bd9Sstevel@tonic-gate 
11407c478bd9Sstevel@tonic-gate /*
11417c478bd9Sstevel@tonic-gate  * Walk the NCA connection structures; follows nca_conn_t next pointers
11427c478bd9Sstevel@tonic-gate  * from a given offset, specified through `wsp->walk_arg'.
11437c478bd9Sstevel@tonic-gate  */
11447c478bd9Sstevel@tonic-gate static int
11457c478bd9Sstevel@tonic-gate nca_conn_walk_step(mdb_walk_state_t *wsp)
11467c478bd9Sstevel@tonic-gate {
11477c478bd9Sstevel@tonic-gate 	nca_conn_t		conn;
11487c478bd9Sstevel@tonic-gate 	int		status;
11497c478bd9Sstevel@tonic-gate 
11507c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr == 0) {
11517c478bd9Sstevel@tonic-gate 		mdb_warn("nca_conn_walk does not support global walks\n");
11527c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
11537c478bd9Sstevel@tonic-gate 	}
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate 	if (mdb_vread(&conn, sizeof (nca_conn_t), wsp->walk_addr) == -1) {
11567c478bd9Sstevel@tonic-gate 		mdb_warn("cannot read nca_conn_t at %p", wsp->walk_addr);
11577c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
11587c478bd9Sstevel@tonic-gate 	}
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, &conn, wsp->walk_cbdata);
11617c478bd9Sstevel@tonic-gate 	if (status != WALK_NEXT)
11627c478bd9Sstevel@tonic-gate 		return (status);
11637c478bd9Sstevel@tonic-gate 
11647c478bd9Sstevel@tonic-gate 	/* LINTED */
11657c478bd9Sstevel@tonic-gate 	wsp->walk_addr = *(uintptr_t *)((caddr_t)&conn +
11667c478bd9Sstevel@tonic-gate 	    (uint_t)(uintptr_t)wsp->walk_arg);
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr == 0)
11697c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
11727c478bd9Sstevel@tonic-gate }
11737c478bd9Sstevel@tonic-gate 
11747c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
11757c478bd9Sstevel@tonic-gate 	{ "nca_conn",	":[-tx]", "print core NCA nca_conn_t info",   nca_conn,
11767c478bd9Sstevel@tonic-gate 	    nca_conn_help },
11777c478bd9Sstevel@tonic-gate 	{ "nca_tcpconn", ":[-t]", "print TCP NCA nca_conn_t info",
11787c478bd9Sstevel@tonic-gate 	    nca_tcpconn, nca_tcpconn_help },
11797c478bd9Sstevel@tonic-gate 	{ "nca_io2",	":[-pv]", "print core NCA io2_t info",    nca_io2,
11807c478bd9Sstevel@tonic-gate 	    nca_io2_help },
11817c478bd9Sstevel@tonic-gate 	{ "nca_node",	":[-rv]", "print core NCA node_t info",   nca_node,
11827c478bd9Sstevel@tonic-gate 	    nca_node_help },
11837c478bd9Sstevel@tonic-gate 	{ "nca_timer",	"?[-e]",  "print core NCA timer info",    nca_timer,
11847c478bd9Sstevel@tonic-gate 	    nca_timer_help },
11857c478bd9Sstevel@tonic-gate 	{ NULL }
11867c478bd9Sstevel@tonic-gate };
11877c478bd9Sstevel@tonic-gate 
11887c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
11897c478bd9Sstevel@tonic-gate 	{ "nca_conn_hash",	"walk the NCA connection hash chain", 0,
11907c478bd9Sstevel@tonic-gate 	    nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, hashnext) },
11917c478bd9Sstevel@tonic-gate 	{ "nca_conn_bind",	"walk the NCA connection bind chain", 0,
11927c478bd9Sstevel@tonic-gate 	    nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, bindnext) },
11937c478bd9Sstevel@tonic-gate 	{ "nca_conn_miss",	"walk the NCA connection miss chain", 0,
11947c478bd9Sstevel@tonic-gate 	    nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, nodenext) },
11957c478bd9Sstevel@tonic-gate 	{ "nca_conn_tw",	"walk the NCA connection TIME_WAIT chain", 0,
11967c478bd9Sstevel@tonic-gate 	    nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, twnext) },
11977c478bd9Sstevel@tonic-gate 
11987c478bd9Sstevel@tonic-gate 	{ "nca_node_file",	"walk the NCA node file chain", 0,
11997c478bd9Sstevel@tonic-gate 	    nca_node_walk_step, 0, (void *)OFFSETOF(node_t, filenext) },
12007c478bd9Sstevel@tonic-gate 	{ "nca_node_hash",	"walk the NCA node hash chain", 0,
12017c478bd9Sstevel@tonic-gate 	    nca_node_walk_step, 0, (void *)OFFSETOF(node_t, hashnext) },
12027c478bd9Sstevel@tonic-gate 	{ "nca_node_chunk",	"walk the NCA node chunk chain", 0,
12037c478bd9Sstevel@tonic-gate 	    nca_node_walk_step, 0, (void *)OFFSETOF(node_t, next) },
12047c478bd9Sstevel@tonic-gate 	{ "nca_node_ctag",	"walk the NCA node ctag chain", 0,
12057c478bd9Sstevel@tonic-gate 	    nca_node_walk_step, 0, (void *)OFFSETOF(node_t, ctagnext) },
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate 	{ "nca_node_plru",	"walk the NCA node physical LRU chain",
12087c478bd9Sstevel@tonic-gate 	    nca_node_lru_walk_init, nca_node_lru_walk_step, 0, NCA_WALK_PLRU },
12097c478bd9Sstevel@tonic-gate 	{ "nca_node_vlru",	"walk the NCA node virtual LRU chain",
12107c478bd9Sstevel@tonic-gate 	    nca_node_lru_walk_init, nca_node_lru_walk_step, 0, NCA_WALK_VLRU },
12117c478bd9Sstevel@tonic-gate 
12127c478bd9Sstevel@tonic-gate 	{ "nca_uri_hash",	"walk the NCA URI node hash table",
12137c478bd9Sstevel@tonic-gate 	    nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncaurihash" },
12147c478bd9Sstevel@tonic-gate 	{ "nca_file_hash",	"walk the NCA file node hash table",
12157c478bd9Sstevel@tonic-gate 	    nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncafilehash" },
12167c478bd9Sstevel@tonic-gate 	{ "nca_ctag_hash",	"walk the NCA ctag node hash table",
12177c478bd9Sstevel@tonic-gate 	    nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncactaghash" },
12187c478bd9Sstevel@tonic-gate 	{ "nca_vnode_hash",	"walk the NCA vnode node hash table",
12197c478bd9Sstevel@tonic-gate 	    nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncavnodehash" },
12207c478bd9Sstevel@tonic-gate 
12217c478bd9Sstevel@tonic-gate 	{ "nca_cpu",		"walk the NCA CPU table",
12227c478bd9Sstevel@tonic-gate 	    nca_cpu_walk_init,   nca_cpu_walk_step },
12237c478bd9Sstevel@tonic-gate 	{ "nca_timer",		"walk the NCA timer table",
12247c478bd9Sstevel@tonic-gate 	    nca_timer_walk_init, nca_timer_walk_step },
12257c478bd9Sstevel@tonic-gate 	{ "nca_connf",		"walk the NCA connection fanout",
12267c478bd9Sstevel@tonic-gate 	    nca_connf_walk_init, nca_connf_walk_step },
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate 	{ NULL }
12297c478bd9Sstevel@tonic-gate };
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
12347c478bd9Sstevel@tonic-gate _mdb_init(void)
12357c478bd9Sstevel@tonic-gate {
12367c478bd9Sstevel@tonic-gate 	return (&modinfo);
12377c478bd9Sstevel@tonic-gate }
1238