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