1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include "lgrp.h" 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 32*0Sstevel@tonic-gate #include <sys/cpuvar.h> 33*0Sstevel@tonic-gate #include <sys/lgrp.h> 34*0Sstevel@tonic-gate #include <sys/cpupart.h> 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate int 37*0Sstevel@tonic-gate print_range(int start, int end, int separator) 38*0Sstevel@tonic-gate { 39*0Sstevel@tonic-gate int count; 40*0Sstevel@tonic-gate char tmp; 41*0Sstevel@tonic-gate char *format; 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate if (start == end) { 44*0Sstevel@tonic-gate /* Unfortunately, mdb_printf returns void */ 45*0Sstevel@tonic-gate format = separator ? ", %d" : "%d"; 46*0Sstevel@tonic-gate mdb_printf(format, start); 47*0Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start); 48*0Sstevel@tonic-gate } else { 49*0Sstevel@tonic-gate format = separator ? ", %d-%d" : "%d-%d"; 50*0Sstevel@tonic-gate mdb_printf(format, start, end); 51*0Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start, end); 52*0Sstevel@tonic-gate } 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate return (count); 55*0Sstevel@tonic-gate } 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate void 58*0Sstevel@tonic-gate print_cpuset_range(ulong_t *cs, int words, int width) 59*0Sstevel@tonic-gate { 60*0Sstevel@tonic-gate int i, j; 61*0Sstevel@tonic-gate ulong_t m; 62*0Sstevel@tonic-gate int in = 0; 63*0Sstevel@tonic-gate int start; 64*0Sstevel@tonic-gate int end; 65*0Sstevel@tonic-gate int count = 0; 66*0Sstevel@tonic-gate int sep = 0; 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate for (i = 0; i < words; i++) 69*0Sstevel@tonic-gate for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1) 70*0Sstevel@tonic-gate if (cs[i] & m) { 71*0Sstevel@tonic-gate if (in == 0) { 72*0Sstevel@tonic-gate start = i * BT_NBIPUL + j; 73*0Sstevel@tonic-gate in = 1; 74*0Sstevel@tonic-gate } 75*0Sstevel@tonic-gate } else { 76*0Sstevel@tonic-gate if (in == 1) { 77*0Sstevel@tonic-gate end = i * BT_NBIPUL + j - 1; 78*0Sstevel@tonic-gate count += print_range(start, end, sep); 79*0Sstevel@tonic-gate sep = 1; 80*0Sstevel@tonic-gate in = 0; 81*0Sstevel@tonic-gate } 82*0Sstevel@tonic-gate } 83*0Sstevel@tonic-gate if (in == 1) { 84*0Sstevel@tonic-gate end = i * BT_NBIPUL - 1; 85*0Sstevel@tonic-gate count += print_range(start, end, sep); 86*0Sstevel@tonic-gate } 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate /* 89*0Sstevel@tonic-gate * print width - count spaces 90*0Sstevel@tonic-gate */ 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate if (width > count) 93*0Sstevel@tonic-gate mdb_printf("%*s", width - count, ""); 94*0Sstevel@tonic-gate } 95*0Sstevel@tonic-gate typedef struct lgrp_cpu_walk { 96*0Sstevel@tonic-gate uintptr_t lcw_firstcpu; 97*0Sstevel@tonic-gate int lcw_cpusleft; 98*0Sstevel@tonic-gate } lgrp_cpu_walk_t; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate int 101*0Sstevel@tonic-gate lgrp_cpulist_walk_init(mdb_walk_state_t *wsp) 102*0Sstevel@tonic-gate { 103*0Sstevel@tonic-gate lgrp_cpu_walk_t *lcw; 104*0Sstevel@tonic-gate lgrp_t lgrp; 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate lcw = mdb_alloc(sizeof (lgrp_cpu_walk_t), UM_SLEEP | UM_GC); 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate if (mdb_vread(&lgrp, sizeof (struct lgrp), wsp->walk_addr) == -1) { 109*0Sstevel@tonic-gate mdb_warn("couldn't read 'lgrp' at %p", wsp->walk_addr); 110*0Sstevel@tonic-gate return (WALK_ERR); 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate lcw->lcw_firstcpu = (uintptr_t)lgrp.lgrp_cpu; 114*0Sstevel@tonic-gate lcw->lcw_cpusleft = lgrp.lgrp_cpucnt; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate wsp->walk_data = lcw; 117*0Sstevel@tonic-gate wsp->walk_addr = lcw->lcw_firstcpu; 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate return (WALK_NEXT); 120*0Sstevel@tonic-gate } 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate int 123*0Sstevel@tonic-gate lgrp_cpulist_walk_step(mdb_walk_state_t *wsp) 124*0Sstevel@tonic-gate { 125*0Sstevel@tonic-gate lgrp_cpu_walk_t *lcw = (lgrp_cpu_walk_t *)wsp->walk_data; 126*0Sstevel@tonic-gate uintptr_t addr = (uintptr_t)wsp->walk_addr; 127*0Sstevel@tonic-gate cpu_t cpu; 128*0Sstevel@tonic-gate int status; 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate if (lcw->lcw_cpusleft-- == 0) 131*0Sstevel@tonic-gate return (WALK_DONE); 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate if (mdb_vread(&cpu, sizeof (cpu_t), addr) == -1) { 134*0Sstevel@tonic-gate mdb_warn("couldn't read 'cpu' at %p", addr); 135*0Sstevel@tonic-gate return (WALK_ERR); 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate status = wsp->walk_callback(addr, &cpu, wsp->walk_cbdata); 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate if (status != WALK_NEXT) 141*0Sstevel@tonic-gate return (status); 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate addr = (uintptr_t)cpu.cpu_next_lgrp; 144*0Sstevel@tonic-gate wsp->walk_addr = addr; 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate if (lcw->lcw_cpusleft == NULL && addr != lcw->lcw_firstcpu) { 147*0Sstevel@tonic-gate mdb_warn("number of cpus in lgroup cpu != lgroup cpucnt\n"); 148*0Sstevel@tonic-gate return (WALK_ERR); 149*0Sstevel@tonic-gate } 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate return (WALK_NEXT); 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate typedef struct lgrp_cpuwalk_cbdata { 155*0Sstevel@tonic-gate uint_t lcc_opt_p; 156*0Sstevel@tonic-gate uint_t lcc_count; 157*0Sstevel@tonic-gate uint_t lcc_used; 158*0Sstevel@tonic-gate uint_t *lcc_psrsetid; 159*0Sstevel@tonic-gate ulong_t **lcc_cpuset; 160*0Sstevel@tonic-gate uint_t *lcc_cpucnt; 161*0Sstevel@tonic-gate int *lcc_loadavg; 162*0Sstevel@tonic-gate } lgrp_cpuwalk_cbdata_t; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate /* ARGSUSED */ 165*0Sstevel@tonic-gate static int 166*0Sstevel@tonic-gate lgrp_cpuwalk_callback(uintptr_t addr, const void *arg, void *cb_data) 167*0Sstevel@tonic-gate { 168*0Sstevel@tonic-gate cpu_t *cpu = (cpu_t *)arg; 169*0Sstevel@tonic-gate lgrp_cpuwalk_cbdata_t *lcc = (lgrp_cpuwalk_cbdata_t *)cb_data; 170*0Sstevel@tonic-gate uint_t opt_p = lcc->lcc_opt_p; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate int offset = 0; 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate /* 175*0Sstevel@tonic-gate * if opt_p is set, we're going to break up info for 176*0Sstevel@tonic-gate * each lgrp by processor set. 177*0Sstevel@tonic-gate */ 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate if (opt_p != 0) { 180*0Sstevel@tonic-gate cpupartid_t cp_id; 181*0Sstevel@tonic-gate cpupart_t cpupart; 182*0Sstevel@tonic-gate lpl_t lpl; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), 186*0Sstevel@tonic-gate (uintptr_t)cpu->cpu_part) == -1) { 187*0Sstevel@tonic-gate mdb_warn("cannot read cpu partition at %p", 188*0Sstevel@tonic-gate cpu->cpu_part); 189*0Sstevel@tonic-gate return (WALK_ERR); 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate cp_id = cpupart.cp_id; 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate for (offset = 0; offset < lcc->lcc_used; offset++) 194*0Sstevel@tonic-gate if (cp_id == lcc->lcc_psrsetid[offset]) { 195*0Sstevel@tonic-gate goto found; 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate if (offset >= lcc->lcc_count) { 199*0Sstevel@tonic-gate mdb_warn( 200*0Sstevel@tonic-gate "number of cpu partitions changed during walk"); 201*0Sstevel@tonic-gate return (WALK_ERR); 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate lcc->lcc_psrsetid[offset] = cp_id; 205*0Sstevel@tonic-gate lcc->lcc_used++; 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate if (mdb_vread(&lpl, sizeof (lpl_t), (uintptr_t)cpu->cpu_lpl) 208*0Sstevel@tonic-gate == -1) { 209*0Sstevel@tonic-gate mdb_warn("Cannot read lpl at %p", cpu->cpu_lpl); 210*0Sstevel@tonic-gate return (WALK_ERR); 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate lcc->lcc_loadavg[offset] = lpl.lpl_loadavg; 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate found: lcc->lcc_cpucnt[offset]++; 217*0Sstevel@tonic-gate BT_SET(lcc->lcc_cpuset[offset], cpu->cpu_id); 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate return (WALK_NEXT); 220*0Sstevel@tonic-gate } 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate /* ARGSUSED */ 224*0Sstevel@tonic-gate int 225*0Sstevel@tonic-gate lgrp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 226*0Sstevel@tonic-gate { 227*0Sstevel@tonic-gate lgrp_t lgrp; 228*0Sstevel@tonic-gate lgrp_cpuwalk_cbdata_t lcc; 229*0Sstevel@tonic-gate int cpusetsize; 230*0Sstevel@tonic-gate int lcpu; /* cpus in lgrp */ 231*0Sstevel@tonic-gate int _ncpu; 232*0Sstevel@tonic-gate int opt_p = 0; /* display partition fraction loads */ 233*0Sstevel@tonic-gate int opt_q = 0; /* display only address. */ 234*0Sstevel@tonic-gate int i; 235*0Sstevel@tonic-gate const char *s_index = NULL, *s_handle = NULL, *s_parent = NULL; 236*0Sstevel@tonic-gate uintptr_t index; 237*0Sstevel@tonic-gate uintptr_t handle; 238*0Sstevel@tonic-gate uintptr_t parent; 239*0Sstevel@tonic-gate int filters = 0; 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 242*0Sstevel@tonic-gate if (mdb_walk_dcmd("lgrptbl", "lgrp", argc, argv) == -1) { 243*0Sstevel@tonic-gate mdb_warn("can't walk 'lgrps'"); 244*0Sstevel@tonic-gate return (DCMD_ERR); 245*0Sstevel@tonic-gate } 246*0Sstevel@tonic-gate return (DCMD_OK); 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 250*0Sstevel@tonic-gate 'p', MDB_OPT_SETBITS, TRUE, &opt_p, 251*0Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &opt_q, 252*0Sstevel@tonic-gate 'P', MDB_OPT_STR, &s_parent, 253*0Sstevel@tonic-gate 'i', MDB_OPT_STR, &s_index, 254*0Sstevel@tonic-gate 'h', MDB_OPT_STR, &s_handle, 255*0Sstevel@tonic-gate NULL) != argc) 256*0Sstevel@tonic-gate return (DCMD_USAGE); 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate if (s_index != NULL) 259*0Sstevel@tonic-gate filters++; 260*0Sstevel@tonic-gate if (s_handle != NULL) 261*0Sstevel@tonic-gate filters++; 262*0Sstevel@tonic-gate if (s_parent != NULL) 263*0Sstevel@tonic-gate filters++; 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT) 266*0Sstevel@tonic-gate opt_q = B_TRUE; 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate if (s_index != NULL) 269*0Sstevel@tonic-gate index = mdb_strtoull(s_index); 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate if (s_parent != NULL) 272*0Sstevel@tonic-gate parent = mdb_strtoull(s_parent); 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate if (s_handle != NULL) { 275*0Sstevel@tonic-gate if (strcmp(s_handle, "NULL") == 0) 276*0Sstevel@tonic-gate handle = (uintptr_t)LGRP_NULL_HANDLE; 277*0Sstevel@tonic-gate else if (strcmp(s_handle, "DEFAULT") == 0) 278*0Sstevel@tonic-gate handle = (uintptr_t)LGRP_DEFAULT_HANDLE; 279*0Sstevel@tonic-gate else 280*0Sstevel@tonic-gate handle = mdb_strtoull(s_handle); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !opt_q) { 284*0Sstevel@tonic-gate if (opt_p == 0) 285*0Sstevel@tonic-gate mdb_printf("%9s %?s %?s %?s %9s %9s\n", 286*0Sstevel@tonic-gate "LGRPID", 287*0Sstevel@tonic-gate "ADDR", 288*0Sstevel@tonic-gate "PARENT", 289*0Sstevel@tonic-gate "PLATHAND", 290*0Sstevel@tonic-gate "#CPU", 291*0Sstevel@tonic-gate "CPUS"); 292*0Sstevel@tonic-gate else 293*0Sstevel@tonic-gate mdb_printf("%9s %9s %9s %9s %9s\n", 294*0Sstevel@tonic-gate "LGRPID", 295*0Sstevel@tonic-gate "PSRSETID", 296*0Sstevel@tonic-gate "LOAD", 297*0Sstevel@tonic-gate "#CPU", 298*0Sstevel@tonic-gate "CPUS"); 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate if (mdb_vread(&lgrp, sizeof (struct lgrp), addr) == -1) { 302*0Sstevel@tonic-gate mdb_warn("unable to read 'lgrp' at %p", addr); 303*0Sstevel@tonic-gate return (DCMD_ERR); 304*0Sstevel@tonic-gate } 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate /* 307*0Sstevel@tonic-gate * Do not report free lgrp unless specifically asked for. 308*0Sstevel@tonic-gate */ 309*0Sstevel@tonic-gate if ((lgrp.lgrp_id == LGRP_NONE) && 310*0Sstevel@tonic-gate ((s_index == NULL) || ((int)index != LGRP_NONE))) 311*0Sstevel@tonic-gate return (DCMD_OK); 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate /* 314*0Sstevel@tonic-gate * If lgrp doesn't pass filtering criteria, don't print anything and 315*0Sstevel@tonic-gate * just return. 316*0Sstevel@tonic-gate */ 317*0Sstevel@tonic-gate if (filters) { 318*0Sstevel@tonic-gate if ((s_parent != NULL) && 319*0Sstevel@tonic-gate parent != (uintptr_t)lgrp.lgrp_parent) 320*0Sstevel@tonic-gate return (DCMD_OK); 321*0Sstevel@tonic-gate if ((s_index != NULL) && index != (uintptr_t)lgrp.lgrp_id) 322*0Sstevel@tonic-gate return (DCMD_OK); 323*0Sstevel@tonic-gate if ((s_handle != NULL) && 324*0Sstevel@tonic-gate handle != (uintptr_t)lgrp.lgrp_plathand) 325*0Sstevel@tonic-gate return (DCMD_OK); 326*0Sstevel@tonic-gate } 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate if (opt_q) { 329*0Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 330*0Sstevel@tonic-gate return (DCMD_OK); 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate /* 335*0Sstevel@tonic-gate * figure out what cpus we've got 336*0Sstevel@tonic-gate */ 337*0Sstevel@tonic-gate if (mdb_readsym(&_ncpu, sizeof (int), "_ncpu") == -1) { 338*0Sstevel@tonic-gate mdb_warn("symbol '_ncpu' not found"); 339*0Sstevel@tonic-gate return (DCMD_ERR); 340*0Sstevel@tonic-gate } 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate /* 343*0Sstevel@tonic-gate * allocate enough space for set of longs to hold cpuid bitfield 344*0Sstevel@tonic-gate */ 345*0Sstevel@tonic-gate if (opt_p) 346*0Sstevel@tonic-gate lcpu = lgrp.lgrp_cpucnt; 347*0Sstevel@tonic-gate else 348*0Sstevel@tonic-gate lcpu = 1; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate cpusetsize = BT_BITOUL(_ncpu) * sizeof (uintptr_t); 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate lcc.lcc_used = 0; 353*0Sstevel@tonic-gate lcc.lcc_cpucnt = mdb_zalloc(sizeof (uint_t) * lcpu, 354*0Sstevel@tonic-gate UM_SLEEP | UM_GC); 355*0Sstevel@tonic-gate lcc.lcc_psrsetid = mdb_zalloc(sizeof (uint_t) * lcpu, 356*0Sstevel@tonic-gate UM_SLEEP | UM_GC); 357*0Sstevel@tonic-gate lcc.lcc_cpuset = mdb_zalloc(sizeof (uintptr_t) * lcpu, 358*0Sstevel@tonic-gate UM_SLEEP | UM_GC); 359*0Sstevel@tonic-gate for (i = 0; i < lcpu; i++) 360*0Sstevel@tonic-gate lcc.lcc_cpuset[i] = mdb_zalloc(cpusetsize, 361*0Sstevel@tonic-gate UM_SLEEP | UM_GC); 362*0Sstevel@tonic-gate lcc.lcc_loadavg = mdb_zalloc(sizeof (int) * lcpu, 363*0Sstevel@tonic-gate UM_SLEEP | UM_GC); 364*0Sstevel@tonic-gate lcc.lcc_count = lcpu; 365*0Sstevel@tonic-gate lcc.lcc_opt_p = opt_p; 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate if (mdb_pwalk("lgrp_cpulist", lgrp_cpuwalk_callback, &lcc, 368*0Sstevel@tonic-gate addr) == -1) { 369*0Sstevel@tonic-gate mdb_warn("unable to walk lgrp_cpulist"); 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate if (opt_p == 0) { 373*0Sstevel@tonic-gate if (lgrp.lgrp_plathand == LGRP_NULL_HANDLE) { 374*0Sstevel@tonic-gate mdb_printf("%9d %?p %?p %?s %9d ", 375*0Sstevel@tonic-gate lgrp.lgrp_id, 376*0Sstevel@tonic-gate addr, 377*0Sstevel@tonic-gate lgrp.lgrp_parent, 378*0Sstevel@tonic-gate "NULL", 379*0Sstevel@tonic-gate lgrp.lgrp_cpucnt); 380*0Sstevel@tonic-gate } else if (lgrp.lgrp_plathand == LGRP_DEFAULT_HANDLE) { 381*0Sstevel@tonic-gate mdb_printf("%9d %?p %?p %?s %9d ", 382*0Sstevel@tonic-gate lgrp.lgrp_id, 383*0Sstevel@tonic-gate addr, 384*0Sstevel@tonic-gate lgrp.lgrp_parent, 385*0Sstevel@tonic-gate "DEFAULT", 386*0Sstevel@tonic-gate lgrp.lgrp_cpucnt); 387*0Sstevel@tonic-gate } else { 388*0Sstevel@tonic-gate mdb_printf("%9d %?p %?p %?p %9d ", 389*0Sstevel@tonic-gate lgrp.lgrp_id, 390*0Sstevel@tonic-gate addr, 391*0Sstevel@tonic-gate lgrp.lgrp_parent, 392*0Sstevel@tonic-gate lgrp.lgrp_plathand, 393*0Sstevel@tonic-gate lgrp.lgrp_cpucnt); 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate if (lgrp.lgrp_cpucnt != 0) { 397*0Sstevel@tonic-gate print_cpuset_range(lcc.lcc_cpuset[0], 398*0Sstevel@tonic-gate cpusetsize/sizeof (ulong_t), 0); 399*0Sstevel@tonic-gate } 400*0Sstevel@tonic-gate mdb_printf("\n"); 401*0Sstevel@tonic-gate } else { 402*0Sstevel@tonic-gate for (i = 0; i < lcc.lcc_used; i++) { 403*0Sstevel@tonic-gate mdb_printf("%9d %9d %9d %9d ", 404*0Sstevel@tonic-gate lgrp.lgrp_id, 405*0Sstevel@tonic-gate lcc.lcc_psrsetid[i], 406*0Sstevel@tonic-gate lcc.lcc_loadavg[i], 407*0Sstevel@tonic-gate lcc.lcc_cpucnt[i]); 408*0Sstevel@tonic-gate if (lcc.lcc_cpucnt[i]) 409*0Sstevel@tonic-gate print_cpuset_range(lcc.lcc_cpuset[i], 410*0Sstevel@tonic-gate cpusetsize/sizeof (ulong_t), 0); 411*0Sstevel@tonic-gate mdb_printf("\n"); 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate return (DCMD_OK); 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate } 417*0Sstevel@tonic-gate 418*0Sstevel@tonic-gate typedef struct lgrp_walk_data { 419*0Sstevel@tonic-gate int lwd_nlgrps; 420*0Sstevel@tonic-gate uintptr_t *lwd_lgrp_tbl; 421*0Sstevel@tonic-gate int lwd_iter; 422*0Sstevel@tonic-gate } lgrp_walk_data_t; 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate int 425*0Sstevel@tonic-gate lgrp_walk_init(mdb_walk_state_t *wsp) 426*0Sstevel@tonic-gate { 427*0Sstevel@tonic-gate lgrp_walk_data_t *lwd; 428*0Sstevel@tonic-gate GElf_Sym sym; 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate lwd = mdb_zalloc(sizeof (lgrp_walk_data_t), UM_SLEEP | UM_GC); 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate if (mdb_readsym(&lwd->lwd_nlgrps, sizeof (int), 433*0Sstevel@tonic-gate "lgrp_alloc_max") == -1) { 434*0Sstevel@tonic-gate mdb_warn("symbol 'lgrp_alloc_max' not found"); 435*0Sstevel@tonic-gate return (WALK_ERR); 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate if (lwd->lwd_nlgrps < 0) { 439*0Sstevel@tonic-gate mdb_warn("lgrp_alloc_max of bounds (%d)\n", lwd->lwd_nlgrps); 440*0Sstevel@tonic-gate return (WALK_ERR); 441*0Sstevel@tonic-gate } 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate lwd->lwd_nlgrps++; 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate if (mdb_lookup_by_name("lgrp_table", &sym) == -1) { 446*0Sstevel@tonic-gate mdb_warn("failed to find 'lgrp_table'"); 447*0Sstevel@tonic-gate return (WALK_ERR); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate /* Get number of valid entries in lgrp_table */ 451*0Sstevel@tonic-gate if (sym.st_size < lwd->lwd_nlgrps * sizeof (lgrp_t *)) { 452*0Sstevel@tonic-gate mdb_warn("lgrp_table size inconsistent with lgrp_alloc_max"); 453*0Sstevel@tonic-gate return (WALK_ERR); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate lwd->lwd_lgrp_tbl = mdb_alloc(sym.st_size, UM_SLEEP | UM_GC); 457*0Sstevel@tonic-gate 458*0Sstevel@tonic-gate if (mdb_readsym(lwd->lwd_lgrp_tbl, lwd->lwd_nlgrps * sizeof (lgrp_t *), 459*0Sstevel@tonic-gate "lgrp_table") == -1) { 460*0Sstevel@tonic-gate mdb_warn("unable to read lgrp_table"); 461*0Sstevel@tonic-gate return (WALK_ERR); 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate wsp->walk_data = lwd; 466*0Sstevel@tonic-gate wsp->walk_addr = lwd->lwd_lgrp_tbl[0]; 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate return (WALK_NEXT); 469*0Sstevel@tonic-gate } 470*0Sstevel@tonic-gate int 471*0Sstevel@tonic-gate lgrp_walk_step(mdb_walk_state_t *wsp) 472*0Sstevel@tonic-gate { 473*0Sstevel@tonic-gate lgrp_walk_data_t *lwd = wsp->walk_data; 474*0Sstevel@tonic-gate lgrp_t lgrp; 475*0Sstevel@tonic-gate int status; 476*0Sstevel@tonic-gate 477*0Sstevel@tonic-gate 478*0Sstevel@tonic-gate if (mdb_vread(&lgrp, sizeof (struct lgrp), 479*0Sstevel@tonic-gate wsp->walk_addr) == -1) { 480*0Sstevel@tonic-gate mdb_warn("unable to read lgrp at %p", 481*0Sstevel@tonic-gate wsp->walk_addr); 482*0Sstevel@tonic-gate return (WALK_ERR); 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &lgrp, 486*0Sstevel@tonic-gate wsp->walk_cbdata); 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate if (status != WALK_NEXT) 489*0Sstevel@tonic-gate return (status); 490*0Sstevel@tonic-gate 491*0Sstevel@tonic-gate lwd->lwd_iter++; 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate if (lwd->lwd_iter >= lwd->lwd_nlgrps) 494*0Sstevel@tonic-gate return (WALK_DONE); 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate wsp->walk_addr = lwd->lwd_lgrp_tbl[lwd->lwd_iter]; 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 499*0Sstevel@tonic-gate mdb_warn("NULL lgrp pointer in lgrp_table[%d]", 500*0Sstevel@tonic-gate lwd->lwd_iter); 501*0Sstevel@tonic-gate return (WALK_ERR); 502*0Sstevel@tonic-gate } 503*0Sstevel@tonic-gate 504*0Sstevel@tonic-gate return (WALK_NEXT); 505*0Sstevel@tonic-gate } 506