xref: /titanic_41/usr/src/cmd/mdb/common/modules/md/dumpmirror.c (revision bf85a12b7c81d0745d5a8aff65baeff50006cde9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include "mdinclude.h"
27 
28 /*
29  * Display an arbitrary bitmap by showing the set bits in the array.
30  * Output will be <start>-<end> for ranges or <position> for singleton bits.
31  */
32 static void
print_mm_bm(unsigned char * bm,uint_t size,char * bm_name)33 print_mm_bm(unsigned char *bm, uint_t size, char *bm_name)
34 {
35 	int	i;
36 	int	first_set = -1;
37 	int	need_comma = 0;
38 
39 	mdb_printf("%s set bits: ", bm_name);
40 	for (i = 0; i < size; i++) {
41 		if (isset(bm, i)) {
42 			if (first_set == -1) {
43 				first_set = i;
44 			}
45 		} else {
46 			if (first_set != -1) {
47 				if (first_set != (i-1)) {
48 					mdb_printf("%s%u-%u",
49 					    (need_comma ? "," : ""),
50 					    first_set, (i-1));
51 				} else {
52 					mdb_printf("%s%u",
53 					    (need_comma ? "," : ""), first_set);
54 				}
55 				need_comma = 1;
56 				first_set = -1;
57 			}
58 		}
59 	}
60 	if (first_set != -1) {
61 		mdb_printf("%s%u-%u", (need_comma ? "," : ""), first_set,
62 		    size-1);
63 	}
64 	mdb_printf("\n");
65 }
66 
67 /*
68  * Print uchar_t sized count fields (typically un_pernode_dirty_map entries)
69  */
70 
71 static void
print_mm_cnt_c(unsigned char * bm,uint_t size,char * bm_name)72 print_mm_cnt_c(unsigned char *bm, uint_t size, char *bm_name)
73 {
74 	int	i;
75 	int	need_comma = 0;
76 
77 	mdb_printf("%s set counts: ", bm_name);
78 	for (i = 0; i < size; i++) {
79 		if (bm[i]) {
80 			mdb_printf("%s(%d,%3d)", (need_comma ? "," : ""), i,
81 			    (uint_t)bm[i]);
82 			need_comma = 1;
83 		}
84 	}
85 	mdb_printf("\n");
86 }
87 
88 static void
print_mm_cnt_w(unsigned short * bm,uint_t size,char * bm_name)89 print_mm_cnt_w(unsigned short *bm, uint_t size, char *bm_name)
90 {
91 	int	i;
92 	int	need_comma = 0;
93 
94 	mdb_printf("%s set counts: ", bm_name);
95 	for (i = 0; i < size; i++) {
96 		if (bm[i]) {
97 			mdb_printf("%s(%d,%5d)", (need_comma ? "," : ""), i,
98 			    (uint_t)bm[i]);
99 			need_comma = 1;
100 		}
101 	}
102 	mdb_printf("\n");
103 }
104 
105 /*
106  * Print the associated bitmaps for the specified mm_unit_t
107  * These are:
108  *	un_pernode_dirty_bm
109  *	un_goingclean_bm
110  *	un_dirty_bm
111  *	un_goingdirty_bm
112  *	un_resync_bm
113  *
114  * Associated counts for unit:
115  *	un_pernode_dirty_sum[] 	(uchar_t)
116  *	un_outstanding_writes[]	(ushort_t)
117  *
118  */
119 
120 /* ARGSUSED */
121 int
printmmbm(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)122 printmmbm(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
123 {
124 	mm_unit_t	mm, *mmp;
125 	unsigned char	*rr_dirty_bm, *rr_goingclean_bm, *rr_goingdirty_bm;
126 	unsigned char	*rr_resync_bm;
127 	uintptr_t	un_dbm, un_gcbm, un_gdbm, un_rrbm, un_pnds, un_ow;
128 	uint_t		num_rr, rr_bitmap_size;
129 	int		i;
130 	uintptr_t	un_pernode_bm;
131 	unsigned char	*rr_pernode_dirty, *rr_pnds;
132 	unsigned short	*rr_ow;
133 	/* just enough for un_pernode_dirty_bm[] plus three digits */
134 	char		pernode_str[25];
135 
136 	if (argc != 0)
137 		return (DCMD_USAGE);
138 
139 	if (!(flags & DCMD_ADDRSPEC)) {
140 		mdb_warn("No mm_unit_t address specified");
141 		return (DCMD_ERR);
142 	}
143 
144 	if (mdb_vread(&mm, sizeof (mm_unit_t), addr) == -1) {
145 		mdb_warn("failed to read mm_unit_t at %p\n", addr);
146 		return (DCMD_ERR);
147 	}
148 
149 	mmp = &mm;
150 
151 	num_rr = mm.un_rrd_num;
152 
153 	un_dbm = (uintptr_t)mmp->un_dirty_bm;
154 	un_gcbm = (uintptr_t)mmp->un_goingclean_bm;
155 	un_gdbm = (uintptr_t)mmp->un_goingdirty_bm;
156 	un_rrbm = (uintptr_t)mmp->un_resync_bm;
157 	un_pnds = (uintptr_t)mmp->un_pernode_dirty_sum;
158 	un_ow = (uintptr_t)mmp->un_outstanding_writes;
159 
160 	rr_bitmap_size = howmany(num_rr, NBBY);
161 	rr_dirty_bm = (unsigned char *)mdb_alloc(rr_bitmap_size,
162 	    UM_SLEEP|UM_GC);
163 	rr_goingclean_bm = (unsigned char *)mdb_alloc(rr_bitmap_size,
164 	    UM_SLEEP|UM_GC);
165 	rr_goingdirty_bm = (unsigned char *)mdb_alloc(rr_bitmap_size,
166 	    UM_SLEEP|UM_GC);
167 	rr_resync_bm = (unsigned char *)mdb_alloc(rr_bitmap_size,
168 	    UM_SLEEP|UM_GC);
169 	rr_pnds = (unsigned char *)mdb_alloc(num_rr, UM_SLEEP|UM_GC);
170 	rr_ow = (unsigned short *)mdb_alloc(num_rr * sizeof (unsigned short),
171 	    UM_SLEEP|UM_GC);
172 
173 	if (mdb_vread(rr_dirty_bm, rr_bitmap_size, un_dbm) == -1) {
174 		mdb_warn("failed to read un_dirty_bm at %p\n", un_dbm);
175 		return (DCMD_ERR);
176 	}
177 	if (mdb_vread(rr_goingclean_bm, rr_bitmap_size, un_gcbm) == -1) {
178 		mdb_warn("failed to read un_goingclean_bm at %p\n", un_gcbm);
179 		return (DCMD_ERR);
180 	}
181 	if (mdb_vread(rr_goingdirty_bm, rr_bitmap_size, un_gdbm) == -1) {
182 		mdb_warn("failed to read un_goingdirty_bm at %p\n", un_gdbm);
183 		return (DCMD_ERR);
184 	}
185 	if (mdb_vread(rr_resync_bm, rr_bitmap_size, un_rrbm) == -1) {
186 		mdb_warn("failed to read un_resync_bm at %p\n", un_rrbm);
187 		return (DCMD_ERR);
188 	}
189 	if (mdb_vread(rr_pnds, num_rr, un_pnds) == -1) {
190 		mdb_warn("failed to read un_pernode_dirty_sum at %p\n",
191 		    un_pnds);
192 		return (DCMD_ERR);
193 	}
194 	if (mdb_vread(rr_ow, num_rr * sizeof (unsigned short), un_ow) == -1) {
195 		mdb_warn("failed to read un_outstanding_writes at %p\n", un_ow);
196 		return (DCMD_ERR);
197 	}
198 
199 	print_mm_bm(rr_dirty_bm, num_rr, "un_dirty_bm");
200 	print_mm_bm(rr_goingclean_bm, num_rr, "un_goingclean_bm");
201 	print_mm_bm(rr_goingdirty_bm, num_rr, "un_goingdirty_bm");
202 	print_mm_bm(rr_resync_bm, num_rr, "un_resync_bm");
203 
204 	/*
205 	 * Load all the un_pernode_bm[] entries and iterate through the non-
206 	 * NULL entries
207 	 */
208 	rr_pernode_dirty = (unsigned char *)mdb_alloc(rr_bitmap_size,
209 	    UM_SLEEP|UM_GC);
210 
211 	for (i = 0; i < 128; i++) {
212 		un_pernode_bm = (uintptr_t)mmp->un_pernode_dirty_bm[i];
213 		if (un_pernode_bm) {
214 			mdb_snprintf(pernode_str, sizeof (pernode_str),
215 			    "un_pernode_dirty_bm[%d]", i);
216 			if (mdb_vread(rr_pernode_dirty, rr_bitmap_size,
217 			    un_pernode_bm) == -1) {
218 				mdb_warn("failed to read %s at %p\n",
219 				    pernode_str, un_pernode_bm);
220 				return (DCMD_ERR);
221 			}
222 			print_mm_bm(rr_pernode_dirty, num_rr, pernode_str);
223 		}
224 	}
225 	print_mm_cnt_c(rr_pnds, num_rr, "un_pernode_dirty_sum");
226 
227 	print_mm_cnt_w(rr_ow, num_rr, "un_outstanding_writes");
228 
229 	return (DCMD_OK);
230 }
231