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 */ 32static void 33print_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 71static void 72print_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 88static void 89print_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 */ 121int 122printmmbm(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