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*c6402783Sakolb * Common Development and Distribution License (the "License"). 6*c6402783Sakolb * 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 */ 21*c6402783Sakolb 227c478bd9Sstevel@tonic-gate /* 23*c6402783Sakolb * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include "lgrp.h" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 327c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h> 337c478bd9Sstevel@tonic-gate #include <sys/lgrp.h> 347c478bd9Sstevel@tonic-gate #include <sys/cpupart.h> 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate int 377c478bd9Sstevel@tonic-gate print_range(int start, int end, int separator) 387c478bd9Sstevel@tonic-gate { 397c478bd9Sstevel@tonic-gate int count; 407c478bd9Sstevel@tonic-gate char tmp; 417c478bd9Sstevel@tonic-gate char *format; 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate if (start == end) { 447c478bd9Sstevel@tonic-gate /* Unfortunately, mdb_printf returns void */ 457c478bd9Sstevel@tonic-gate format = separator ? ", %d" : "%d"; 467c478bd9Sstevel@tonic-gate mdb_printf(format, start); 477c478bd9Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start); 487c478bd9Sstevel@tonic-gate } else { 497c478bd9Sstevel@tonic-gate format = separator ? ", %d-%d" : "%d-%d"; 507c478bd9Sstevel@tonic-gate mdb_printf(format, start, end); 517c478bd9Sstevel@tonic-gate count = mdb_snprintf(&tmp, 1, format, start, end); 527c478bd9Sstevel@tonic-gate } 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate return (count); 557c478bd9Sstevel@tonic-gate } 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate void 587c478bd9Sstevel@tonic-gate print_cpuset_range(ulong_t *cs, int words, int width) 597c478bd9Sstevel@tonic-gate { 607c478bd9Sstevel@tonic-gate int i, j; 617c478bd9Sstevel@tonic-gate ulong_t m; 627c478bd9Sstevel@tonic-gate int in = 0; 637c478bd9Sstevel@tonic-gate int start; 647c478bd9Sstevel@tonic-gate int end; 657c478bd9Sstevel@tonic-gate int count = 0; 667c478bd9Sstevel@tonic-gate int sep = 0; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate for (i = 0; i < words; i++) 697c478bd9Sstevel@tonic-gate for (j = 0, m = 1; j < BT_NBIPUL; j++, m <<= 1) 707c478bd9Sstevel@tonic-gate if (cs[i] & m) { 717c478bd9Sstevel@tonic-gate if (in == 0) { 727c478bd9Sstevel@tonic-gate start = i * BT_NBIPUL + j; 737c478bd9Sstevel@tonic-gate in = 1; 747c478bd9Sstevel@tonic-gate } 757c478bd9Sstevel@tonic-gate } else { 767c478bd9Sstevel@tonic-gate if (in == 1) { 777c478bd9Sstevel@tonic-gate end = i * BT_NBIPUL + j - 1; 787c478bd9Sstevel@tonic-gate count += print_range(start, end, sep); 797c478bd9Sstevel@tonic-gate sep = 1; 807c478bd9Sstevel@tonic-gate in = 0; 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate if (in == 1) { 847c478bd9Sstevel@tonic-gate end = i * BT_NBIPUL - 1; 857c478bd9Sstevel@tonic-gate count += print_range(start, end, sep); 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* 897c478bd9Sstevel@tonic-gate * print width - count spaces 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate if (width > count) 937c478bd9Sstevel@tonic-gate mdb_printf("%*s", width - count, ""); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate typedef struct lgrp_cpu_walk { 967c478bd9Sstevel@tonic-gate uintptr_t lcw_firstcpu; 977c478bd9Sstevel@tonic-gate int lcw_cpusleft; 987c478bd9Sstevel@tonic-gate } lgrp_cpu_walk_t; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate int 1017c478bd9Sstevel@tonic-gate lgrp_cpulist_walk_init(mdb_walk_state_t *wsp) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate lgrp_cpu_walk_t *lcw; 1047c478bd9Sstevel@tonic-gate lgrp_t lgrp; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate lcw = mdb_alloc(sizeof (lgrp_cpu_walk_t), UM_SLEEP | UM_GC); 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate if (mdb_vread(&lgrp, sizeof (struct lgrp), wsp->walk_addr) == -1) { 1097c478bd9Sstevel@tonic-gate mdb_warn("couldn't read 'lgrp' at %p", wsp->walk_addr); 1107c478bd9Sstevel@tonic-gate return (WALK_ERR); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate lcw->lcw_firstcpu = (uintptr_t)lgrp.lgrp_cpu; 1147c478bd9Sstevel@tonic-gate lcw->lcw_cpusleft = lgrp.lgrp_cpucnt; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate wsp->walk_data = lcw; 1177c478bd9Sstevel@tonic-gate wsp->walk_addr = lcw->lcw_firstcpu; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate return (WALK_NEXT); 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate int 1237c478bd9Sstevel@tonic-gate lgrp_cpulist_walk_step(mdb_walk_state_t *wsp) 1247c478bd9Sstevel@tonic-gate { 1257c478bd9Sstevel@tonic-gate lgrp_cpu_walk_t *lcw = (lgrp_cpu_walk_t *)wsp->walk_data; 1267c478bd9Sstevel@tonic-gate uintptr_t addr = (uintptr_t)wsp->walk_addr; 1277c478bd9Sstevel@tonic-gate cpu_t cpu; 1287c478bd9Sstevel@tonic-gate int status; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate if (lcw->lcw_cpusleft-- == 0) 1317c478bd9Sstevel@tonic-gate return (WALK_DONE); 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate if (mdb_vread(&cpu, sizeof (cpu_t), addr) == -1) { 1347c478bd9Sstevel@tonic-gate mdb_warn("couldn't read 'cpu' at %p", addr); 1357c478bd9Sstevel@tonic-gate return (WALK_ERR); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate status = wsp->walk_callback(addr, &cpu, wsp->walk_cbdata); 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate if (status != WALK_NEXT) 1417c478bd9Sstevel@tonic-gate return (status); 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate addr = (uintptr_t)cpu.cpu_next_lgrp; 1447c478bd9Sstevel@tonic-gate wsp->walk_addr = addr; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate if (lcw->lcw_cpusleft == NULL && addr != lcw->lcw_firstcpu) { 1477c478bd9Sstevel@tonic-gate mdb_warn("number of cpus in lgroup cpu != lgroup cpucnt\n"); 1487c478bd9Sstevel@tonic-gate return (WALK_ERR); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate return (WALK_NEXT); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate typedef struct lgrp_cpuwalk_cbdata { 1557c478bd9Sstevel@tonic-gate uint_t lcc_opt_p; 1567c478bd9Sstevel@tonic-gate uint_t lcc_count; 1577c478bd9Sstevel@tonic-gate uint_t lcc_used; 1587c478bd9Sstevel@tonic-gate uint_t *lcc_psrsetid; 1597c478bd9Sstevel@tonic-gate ulong_t **lcc_cpuset; 1607c478bd9Sstevel@tonic-gate uint_t *lcc_cpucnt; 1617c478bd9Sstevel@tonic-gate int *lcc_loadavg; 1627c478bd9Sstevel@tonic-gate } lgrp_cpuwalk_cbdata_t; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1657c478bd9Sstevel@tonic-gate static int 1667c478bd9Sstevel@tonic-gate lgrp_cpuwalk_callback(uintptr_t addr, const void *arg, void *cb_data) 1677c478bd9Sstevel@tonic-gate { 1687c478bd9Sstevel@tonic-gate cpu_t *cpu = (cpu_t *)arg; 1697c478bd9Sstevel@tonic-gate lgrp_cpuwalk_cbdata_t *lcc = (lgrp_cpuwalk_cbdata_t *)cb_data; 1707c478bd9Sstevel@tonic-gate uint_t opt_p = lcc->lcc_opt_p; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate int offset = 0; 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate /* 1757c478bd9Sstevel@tonic-gate * if opt_p is set, we're going to break up info for 1767c478bd9Sstevel@tonic-gate * each lgrp by processor set. 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate if (opt_p != 0) { 1807c478bd9Sstevel@tonic-gate cpupartid_t cp_id; 1817c478bd9Sstevel@tonic-gate cpupart_t cpupart; 1827c478bd9Sstevel@tonic-gate lpl_t lpl; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), 1867c478bd9Sstevel@tonic-gate (uintptr_t)cpu->cpu_part) == -1) { 1877c478bd9Sstevel@tonic-gate mdb_warn("cannot read cpu partition at %p", 1887c478bd9Sstevel@tonic-gate cpu->cpu_part); 1897c478bd9Sstevel@tonic-gate return (WALK_ERR); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate cp_id = cpupart.cp_id; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate for (offset = 0; offset < lcc->lcc_used; offset++) 1947c478bd9Sstevel@tonic-gate if (cp_id == lcc->lcc_psrsetid[offset]) { 1957c478bd9Sstevel@tonic-gate goto found; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate if (offset >= lcc->lcc_count) { 1997c478bd9Sstevel@tonic-gate mdb_warn( 2007c478bd9Sstevel@tonic-gate "number of cpu partitions changed during walk"); 2017c478bd9Sstevel@tonic-gate return (WALK_ERR); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate lcc->lcc_psrsetid[offset] = cp_id; 2057c478bd9Sstevel@tonic-gate lcc->lcc_used++; 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate if (mdb_vread(&lpl, sizeof (lpl_t), (uintptr_t)cpu->cpu_lpl) 2087c478bd9Sstevel@tonic-gate == -1) { 2097c478bd9Sstevel@tonic-gate mdb_warn("Cannot read lpl at %p", cpu->cpu_lpl); 2107c478bd9Sstevel@tonic-gate return (WALK_ERR); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate lcc->lcc_loadavg[offset] = lpl.lpl_loadavg; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate found: lcc->lcc_cpucnt[offset]++; 2177c478bd9Sstevel@tonic-gate BT_SET(lcc->lcc_cpuset[offset], cpu->cpu_id); 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate return (WALK_NEXT); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2247c478bd9Sstevel@tonic-gate int 2257c478bd9Sstevel@tonic-gate lgrp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2267c478bd9Sstevel@tonic-gate { 2277c478bd9Sstevel@tonic-gate lgrp_t lgrp; 2287c478bd9Sstevel@tonic-gate lgrp_cpuwalk_cbdata_t lcc; 2297c478bd9Sstevel@tonic-gate int cpusetsize; 2307c478bd9Sstevel@tonic-gate int lcpu; /* cpus in lgrp */ 2317c478bd9Sstevel@tonic-gate int _ncpu; 2327c478bd9Sstevel@tonic-gate int opt_p = 0; /* display partition fraction loads */ 2337c478bd9Sstevel@tonic-gate int opt_q = 0; /* display only address. */ 2347c478bd9Sstevel@tonic-gate int i; 2357c478bd9Sstevel@tonic-gate const char *s_index = NULL, *s_handle = NULL, *s_parent = NULL; 2367c478bd9Sstevel@tonic-gate uintptr_t index; 2377c478bd9Sstevel@tonic-gate uintptr_t handle; 2387c478bd9Sstevel@tonic-gate uintptr_t parent; 2397c478bd9Sstevel@tonic-gate int filters = 0; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 2427c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("lgrptbl", "lgrp", argc, argv) == -1) { 2437c478bd9Sstevel@tonic-gate mdb_warn("can't walk 'lgrps'"); 2447c478bd9Sstevel@tonic-gate return (DCMD_ERR); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate return (DCMD_OK); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 2507c478bd9Sstevel@tonic-gate 'p', MDB_OPT_SETBITS, TRUE, &opt_p, 2517c478bd9Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &opt_q, 2527c478bd9Sstevel@tonic-gate 'P', MDB_OPT_STR, &s_parent, 2537c478bd9Sstevel@tonic-gate 'i', MDB_OPT_STR, &s_index, 2547c478bd9Sstevel@tonic-gate 'h', MDB_OPT_STR, &s_handle, 2557c478bd9Sstevel@tonic-gate NULL) != argc) 2567c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate if (s_index != NULL) 2597c478bd9Sstevel@tonic-gate filters++; 2607c478bd9Sstevel@tonic-gate if (s_handle != NULL) 2617c478bd9Sstevel@tonic-gate filters++; 2627c478bd9Sstevel@tonic-gate if (s_parent != NULL) 2637c478bd9Sstevel@tonic-gate filters++; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT) 2667c478bd9Sstevel@tonic-gate opt_q = B_TRUE; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if (s_index != NULL) 2697c478bd9Sstevel@tonic-gate index = mdb_strtoull(s_index); 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate if (s_parent != NULL) 2727c478bd9Sstevel@tonic-gate parent = mdb_strtoull(s_parent); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (s_handle != NULL) { 2757c478bd9Sstevel@tonic-gate if (strcmp(s_handle, "NULL") == 0) 2767c478bd9Sstevel@tonic-gate handle = (uintptr_t)LGRP_NULL_HANDLE; 2777c478bd9Sstevel@tonic-gate else if (strcmp(s_handle, "DEFAULT") == 0) 2787c478bd9Sstevel@tonic-gate handle = (uintptr_t)LGRP_DEFAULT_HANDLE; 2797c478bd9Sstevel@tonic-gate else 2807c478bd9Sstevel@tonic-gate handle = mdb_strtoull(s_handle); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !opt_q) { 2847c478bd9Sstevel@tonic-gate if (opt_p == 0) 2857c478bd9Sstevel@tonic-gate mdb_printf("%9s %?s %?s %?s %9s %9s\n", 2867c478bd9Sstevel@tonic-gate "LGRPID", 2877c478bd9Sstevel@tonic-gate "ADDR", 2887c478bd9Sstevel@tonic-gate "PARENT", 2897c478bd9Sstevel@tonic-gate "PLATHAND", 2907c478bd9Sstevel@tonic-gate "#CPU", 2917c478bd9Sstevel@tonic-gate "CPUS"); 2927c478bd9Sstevel@tonic-gate else 2937c478bd9Sstevel@tonic-gate mdb_printf("%9s %9s %9s %9s %9s\n", 2947c478bd9Sstevel@tonic-gate "LGRPID", 2957c478bd9Sstevel@tonic-gate "PSRSETID", 2967c478bd9Sstevel@tonic-gate "LOAD", 2977c478bd9Sstevel@tonic-gate "#CPU", 2987c478bd9Sstevel@tonic-gate "CPUS"); 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate if (mdb_vread(&lgrp, sizeof (struct lgrp), addr) == -1) { 3027c478bd9Sstevel@tonic-gate mdb_warn("unable to read 'lgrp' at %p", addr); 3037c478bd9Sstevel@tonic-gate return (DCMD_ERR); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate /* 3077c478bd9Sstevel@tonic-gate * Do not report free lgrp unless specifically asked for. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate if ((lgrp.lgrp_id == LGRP_NONE) && 3107c478bd9Sstevel@tonic-gate ((s_index == NULL) || ((int)index != LGRP_NONE))) 3117c478bd9Sstevel@tonic-gate return (DCMD_OK); 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * If lgrp doesn't pass filtering criteria, don't print anything and 3157c478bd9Sstevel@tonic-gate * just return. 3167c478bd9Sstevel@tonic-gate */ 3177c478bd9Sstevel@tonic-gate if (filters) { 3187c478bd9Sstevel@tonic-gate if ((s_parent != NULL) && 3197c478bd9Sstevel@tonic-gate parent != (uintptr_t)lgrp.lgrp_parent) 3207c478bd9Sstevel@tonic-gate return (DCMD_OK); 3217c478bd9Sstevel@tonic-gate if ((s_index != NULL) && index != (uintptr_t)lgrp.lgrp_id) 3227c478bd9Sstevel@tonic-gate return (DCMD_OK); 3237c478bd9Sstevel@tonic-gate if ((s_handle != NULL) && 3247c478bd9Sstevel@tonic-gate handle != (uintptr_t)lgrp.lgrp_plathand) 3257c478bd9Sstevel@tonic-gate return (DCMD_OK); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if (opt_q) { 3297c478bd9Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 3307c478bd9Sstevel@tonic-gate return (DCMD_OK); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate /* 3357c478bd9Sstevel@tonic-gate * figure out what cpus we've got 3367c478bd9Sstevel@tonic-gate */ 3377c478bd9Sstevel@tonic-gate if (mdb_readsym(&_ncpu, sizeof (int), "_ncpu") == -1) { 3387c478bd9Sstevel@tonic-gate mdb_warn("symbol '_ncpu' not found"); 3397c478bd9Sstevel@tonic-gate return (DCMD_ERR); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate /* 3437c478bd9Sstevel@tonic-gate * allocate enough space for set of longs to hold cpuid bitfield 3447c478bd9Sstevel@tonic-gate */ 3457c478bd9Sstevel@tonic-gate if (opt_p) 3467c478bd9Sstevel@tonic-gate lcpu = lgrp.lgrp_cpucnt; 3477c478bd9Sstevel@tonic-gate else 3487c478bd9Sstevel@tonic-gate lcpu = 1; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate cpusetsize = BT_BITOUL(_ncpu) * sizeof (uintptr_t); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate lcc.lcc_used = 0; 3537c478bd9Sstevel@tonic-gate lcc.lcc_cpucnt = mdb_zalloc(sizeof (uint_t) * lcpu, 3547c478bd9Sstevel@tonic-gate UM_SLEEP | UM_GC); 3557c478bd9Sstevel@tonic-gate lcc.lcc_psrsetid = mdb_zalloc(sizeof (uint_t) * lcpu, 3567c478bd9Sstevel@tonic-gate UM_SLEEP | UM_GC); 3577c478bd9Sstevel@tonic-gate lcc.lcc_cpuset = mdb_zalloc(sizeof (uintptr_t) * lcpu, 3587c478bd9Sstevel@tonic-gate UM_SLEEP | UM_GC); 3597c478bd9Sstevel@tonic-gate for (i = 0; i < lcpu; i++) 3607c478bd9Sstevel@tonic-gate lcc.lcc_cpuset[i] = mdb_zalloc(cpusetsize, 3617c478bd9Sstevel@tonic-gate UM_SLEEP | UM_GC); 3627c478bd9Sstevel@tonic-gate lcc.lcc_loadavg = mdb_zalloc(sizeof (int) * lcpu, 3637c478bd9Sstevel@tonic-gate UM_SLEEP | UM_GC); 3647c478bd9Sstevel@tonic-gate lcc.lcc_count = lcpu; 3657c478bd9Sstevel@tonic-gate lcc.lcc_opt_p = opt_p; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate if (mdb_pwalk("lgrp_cpulist", lgrp_cpuwalk_callback, &lcc, 3687c478bd9Sstevel@tonic-gate addr) == -1) { 3697c478bd9Sstevel@tonic-gate mdb_warn("unable to walk lgrp_cpulist"); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate if (opt_p == 0) { 3737c478bd9Sstevel@tonic-gate if (lgrp.lgrp_plathand == LGRP_NULL_HANDLE) { 3747c478bd9Sstevel@tonic-gate mdb_printf("%9d %?p %?p %?s %9d ", 3757c478bd9Sstevel@tonic-gate lgrp.lgrp_id, 3767c478bd9Sstevel@tonic-gate addr, 3777c478bd9Sstevel@tonic-gate lgrp.lgrp_parent, 3787c478bd9Sstevel@tonic-gate "NULL", 3797c478bd9Sstevel@tonic-gate lgrp.lgrp_cpucnt); 3807c478bd9Sstevel@tonic-gate } else if (lgrp.lgrp_plathand == LGRP_DEFAULT_HANDLE) { 3817c478bd9Sstevel@tonic-gate mdb_printf("%9d %?p %?p %?s %9d ", 3827c478bd9Sstevel@tonic-gate lgrp.lgrp_id, 3837c478bd9Sstevel@tonic-gate addr, 3847c478bd9Sstevel@tonic-gate lgrp.lgrp_parent, 3857c478bd9Sstevel@tonic-gate "DEFAULT", 3867c478bd9Sstevel@tonic-gate lgrp.lgrp_cpucnt); 3877c478bd9Sstevel@tonic-gate } else { 3887c478bd9Sstevel@tonic-gate mdb_printf("%9d %?p %?p %?p %9d ", 3897c478bd9Sstevel@tonic-gate lgrp.lgrp_id, 3907c478bd9Sstevel@tonic-gate addr, 3917c478bd9Sstevel@tonic-gate lgrp.lgrp_parent, 3927c478bd9Sstevel@tonic-gate lgrp.lgrp_plathand, 3937c478bd9Sstevel@tonic-gate lgrp.lgrp_cpucnt); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate if (lgrp.lgrp_cpucnt != 0) { 3977c478bd9Sstevel@tonic-gate print_cpuset_range(lcc.lcc_cpuset[0], 3987c478bd9Sstevel@tonic-gate cpusetsize/sizeof (ulong_t), 0); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate mdb_printf("\n"); 4017c478bd9Sstevel@tonic-gate } else { 4027c478bd9Sstevel@tonic-gate for (i = 0; i < lcc.lcc_used; i++) { 4037c478bd9Sstevel@tonic-gate mdb_printf("%9d %9d %9d %9d ", 4047c478bd9Sstevel@tonic-gate lgrp.lgrp_id, 4057c478bd9Sstevel@tonic-gate lcc.lcc_psrsetid[i], 4067c478bd9Sstevel@tonic-gate lcc.lcc_loadavg[i], 4077c478bd9Sstevel@tonic-gate lcc.lcc_cpucnt[i]); 4087c478bd9Sstevel@tonic-gate if (lcc.lcc_cpucnt[i]) 4097c478bd9Sstevel@tonic-gate print_cpuset_range(lcc.lcc_cpuset[i], 4107c478bd9Sstevel@tonic-gate cpusetsize/sizeof (ulong_t), 0); 4117c478bd9Sstevel@tonic-gate mdb_printf("\n"); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate return (DCMD_OK); 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate typedef struct lgrp_walk_data { 4197c478bd9Sstevel@tonic-gate int lwd_nlgrps; 4207c478bd9Sstevel@tonic-gate uintptr_t *lwd_lgrp_tbl; 4217c478bd9Sstevel@tonic-gate int lwd_iter; 4227c478bd9Sstevel@tonic-gate } lgrp_walk_data_t; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate int 4257c478bd9Sstevel@tonic-gate lgrp_walk_init(mdb_walk_state_t *wsp) 4267c478bd9Sstevel@tonic-gate { 4277c478bd9Sstevel@tonic-gate lgrp_walk_data_t *lwd; 4287c478bd9Sstevel@tonic-gate GElf_Sym sym; 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate lwd = mdb_zalloc(sizeof (lgrp_walk_data_t), UM_SLEEP | UM_GC); 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate if (mdb_readsym(&lwd->lwd_nlgrps, sizeof (int), 4337c478bd9Sstevel@tonic-gate "lgrp_alloc_max") == -1) { 4347c478bd9Sstevel@tonic-gate mdb_warn("symbol 'lgrp_alloc_max' not found"); 4357c478bd9Sstevel@tonic-gate return (WALK_ERR); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate if (lwd->lwd_nlgrps < 0) { 4397c478bd9Sstevel@tonic-gate mdb_warn("lgrp_alloc_max of bounds (%d)\n", lwd->lwd_nlgrps); 4407c478bd9Sstevel@tonic-gate return (WALK_ERR); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate lwd->lwd_nlgrps++; 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate if (mdb_lookup_by_name("lgrp_table", &sym) == -1) { 4467c478bd9Sstevel@tonic-gate mdb_warn("failed to find 'lgrp_table'"); 4477c478bd9Sstevel@tonic-gate return (WALK_ERR); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate /* Get number of valid entries in lgrp_table */ 4517c478bd9Sstevel@tonic-gate if (sym.st_size < lwd->lwd_nlgrps * sizeof (lgrp_t *)) { 4527c478bd9Sstevel@tonic-gate mdb_warn("lgrp_table size inconsistent with lgrp_alloc_max"); 4537c478bd9Sstevel@tonic-gate return (WALK_ERR); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate lwd->lwd_lgrp_tbl = mdb_alloc(sym.st_size, UM_SLEEP | UM_GC); 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate if (mdb_readsym(lwd->lwd_lgrp_tbl, lwd->lwd_nlgrps * sizeof (lgrp_t *), 4597c478bd9Sstevel@tonic-gate "lgrp_table") == -1) { 4607c478bd9Sstevel@tonic-gate mdb_warn("unable to read lgrp_table"); 4617c478bd9Sstevel@tonic-gate return (WALK_ERR); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate wsp->walk_data = lwd; 4667c478bd9Sstevel@tonic-gate wsp->walk_addr = lwd->lwd_lgrp_tbl[0]; 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate return (WALK_NEXT); 4697c478bd9Sstevel@tonic-gate } 470*c6402783Sakolb 471*c6402783Sakolb /* 472*c6402783Sakolb * Common routine for several walkers. 473*c6402783Sakolb * Read lgroup from wsp->walk_addr and call wsp->walk_callback for it. 474*c6402783Sakolb * Normally returns the result of the callback. 475*c6402783Sakolb * Returns WALK_DONE if walk_addr is NULL and WALK_ERR if cannot read the 476*c6402783Sakolb * lgroup. 477*c6402783Sakolb */ 478*c6402783Sakolb static int 479*c6402783Sakolb lgrp_walk_step_common(mdb_walk_state_t *wsp) 480*c6402783Sakolb { 481*c6402783Sakolb lgrp_t lgrp; 482*c6402783Sakolb 483*c6402783Sakolb if (wsp->walk_addr == NULL) 484*c6402783Sakolb return (WALK_DONE); 485*c6402783Sakolb 486*c6402783Sakolb if (mdb_vread(&lgrp, sizeof (lgrp_t), wsp->walk_addr) == -1) { 487*c6402783Sakolb mdb_warn("unable to read lgrp at %p", wsp->walk_addr); 488*c6402783Sakolb return (WALK_ERR); 489*c6402783Sakolb } 490*c6402783Sakolb 491*c6402783Sakolb return (wsp->walk_callback(wsp->walk_addr, &lgrp, wsp->walk_cbdata)); 492*c6402783Sakolb } 493*c6402783Sakolb 494*c6402783Sakolb /* 495*c6402783Sakolb * Get one lgroup from the lgroup table and adjust lwd_iter to point to the next 496*c6402783Sakolb * one. 497*c6402783Sakolb */ 4987c478bd9Sstevel@tonic-gate int 4997c478bd9Sstevel@tonic-gate lgrp_walk_step(mdb_walk_state_t *wsp) 5007c478bd9Sstevel@tonic-gate { 5017c478bd9Sstevel@tonic-gate lgrp_walk_data_t *lwd = wsp->walk_data; 502*c6402783Sakolb int status = lgrp_walk_step_common(wsp); 5037c478bd9Sstevel@tonic-gate 504*c6402783Sakolb if (status == WALK_NEXT) { 5057c478bd9Sstevel@tonic-gate lwd->lwd_iter++; 5067c478bd9Sstevel@tonic-gate 507*c6402783Sakolb if (lwd->lwd_iter >= lwd->lwd_nlgrps) { 508*c6402783Sakolb status = WALK_DONE; 509*c6402783Sakolb } else { 5107c478bd9Sstevel@tonic-gate wsp->walk_addr = lwd->lwd_lgrp_tbl[lwd->lwd_iter]; 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 5137c478bd9Sstevel@tonic-gate mdb_warn("NULL lgrp pointer in lgrp_table[%d]", 5147c478bd9Sstevel@tonic-gate lwd->lwd_iter); 5157c478bd9Sstevel@tonic-gate return (WALK_ERR); 5167c478bd9Sstevel@tonic-gate } 517*c6402783Sakolb } 518*c6402783Sakolb } 519*c6402783Sakolb 520*c6402783Sakolb return (status); 521*c6402783Sakolb } 522*c6402783Sakolb 523*c6402783Sakolb /* 524*c6402783Sakolb * Initialize walker to traverse parents of lgroups. Nothing to do here. 525*c6402783Sakolb */ 526*c6402783Sakolb /* ARGSUSED */ 527*c6402783Sakolb int 528*c6402783Sakolb lgrp_parents_walk_init(mdb_walk_state_t *wsp) 529*c6402783Sakolb { 530*c6402783Sakolb return (WALK_NEXT); 531*c6402783Sakolb } 532*c6402783Sakolb 533*c6402783Sakolb /* 534*c6402783Sakolb * Call wsp callback on current lgroup in wsp and replace the lgroup with its 535*c6402783Sakolb * parent. 536*c6402783Sakolb */ 537*c6402783Sakolb int 538*c6402783Sakolb lgrp_parents_walk_step(mdb_walk_state_t *wsp) 539*c6402783Sakolb { 540*c6402783Sakolb lgrp_t lgrp; 541*c6402783Sakolb int status; 542*c6402783Sakolb 543*c6402783Sakolb if (wsp->walk_addr == NULL) 544*c6402783Sakolb return (WALK_DONE); 545*c6402783Sakolb 546*c6402783Sakolb if (mdb_vread(&lgrp, sizeof (struct lgrp), wsp->walk_addr) == -1) { 547*c6402783Sakolb mdb_warn("couldn't read 'lgrp' at %p", wsp->walk_addr); 548*c6402783Sakolb return (WALK_ERR); 549*c6402783Sakolb } 550*c6402783Sakolb 551*c6402783Sakolb status = wsp->walk_callback(wsp->walk_addr, &lgrp, wsp->walk_cbdata); 552*c6402783Sakolb 553*c6402783Sakolb if (status == WALK_NEXT) 554*c6402783Sakolb wsp->walk_addr = (uintptr_t)lgrp.lgrp_parent; 555*c6402783Sakolb 556*c6402783Sakolb return (status); 557*c6402783Sakolb } 558*c6402783Sakolb 559*c6402783Sakolb /* 560*c6402783Sakolb * Given the set return the ID of the first member of the set. 561*c6402783Sakolb * Returns LGRP_NONE if the set has no elements smaller than max_lgrp. 562*c6402783Sakolb */ 563*c6402783Sakolb static lgrp_id_t 564*c6402783Sakolb lgrp_set_get_first(klgrpset_t set, int max_lgrp) 565*c6402783Sakolb { 566*c6402783Sakolb lgrp_id_t id; 567*c6402783Sakolb klgrpset_t bit = 1; 568*c6402783Sakolb 569*c6402783Sakolb if (set == (klgrpset_t)0) 570*c6402783Sakolb return (LGRP_NONE); 571*c6402783Sakolb 572*c6402783Sakolb for (id = 0; (id < max_lgrp) && !(set & bit); id++, bit <<= 1) 573*c6402783Sakolb ; 574*c6402783Sakolb 575*c6402783Sakolb if (id >= max_lgrp) 576*c6402783Sakolb id = LGRP_NONE; 577*c6402783Sakolb 578*c6402783Sakolb return (id); 579*c6402783Sakolb } 580*c6402783Sakolb 581*c6402783Sakolb /* 582*c6402783Sakolb * lgrp_set_walk_data is used to walk lgroups specified by a set. 583*c6402783Sakolb * On every iteration one element is removed from the set. 584*c6402783Sakolb */ 585*c6402783Sakolb typedef struct lgrp_set_walk_data { 586*c6402783Sakolb int lswd_nlgrps; /* Number of lgroups */ 587*c6402783Sakolb uintptr_t *lwsd_lgrp_tbl; /* Full lgroup table */ 588*c6402783Sakolb klgrpset_t lwsd_set; /* Set of lgroups to walk */ 589*c6402783Sakolb } lgrp_set_walk_data_t; 590*c6402783Sakolb 591*c6402783Sakolb /* 592*c6402783Sakolb * Initialize iterator for walkers over a set of lgroups 593*c6402783Sakolb */ 594*c6402783Sakolb static int 595*c6402783Sakolb lgrp_set_walk_init(mdb_walk_state_t *wsp, klgrpset_t set) 596*c6402783Sakolb { 597*c6402783Sakolb lgrp_set_walk_data_t *lwsd; 598*c6402783Sakolb int nlgrps; 599*c6402783Sakolb lgrp_id_t id; 600*c6402783Sakolb GElf_Sym sym; 601*c6402783Sakolb 602*c6402783Sakolb /* Nothing to do if the set is empty */ 603*c6402783Sakolb if (set == (klgrpset_t)0) 604*c6402783Sakolb return (WALK_DONE); 605*c6402783Sakolb 606*c6402783Sakolb lwsd = mdb_zalloc(sizeof (lgrp_set_walk_data_t), UM_SLEEP | UM_GC); 607*c6402783Sakolb 608*c6402783Sakolb /* Get the total number of lgroups */ 609*c6402783Sakolb if (mdb_readsym(&nlgrps, sizeof (int), "lgrp_alloc_max") == -1) { 610*c6402783Sakolb mdb_warn("symbol 'lgrp_alloc_max' not found"); 611*c6402783Sakolb return (WALK_ERR); 612*c6402783Sakolb } 613*c6402783Sakolb 614*c6402783Sakolb if (nlgrps < 0) { 615*c6402783Sakolb mdb_warn("lgrp_alloc_max of bounds (%d)\n", nlgrps); 616*c6402783Sakolb return (WALK_ERR); 617*c6402783Sakolb } 618*c6402783Sakolb 619*c6402783Sakolb nlgrps++; 620*c6402783Sakolb 621*c6402783Sakolb /* Find ID of the first lgroup in the set */ 622*c6402783Sakolb if ((id = lgrp_set_get_first(set, nlgrps)) == LGRP_NONE) { 623*c6402783Sakolb mdb_warn("No set elements within %d lgroups\n", nlgrps); 624*c6402783Sakolb return (WALK_ERR); 625*c6402783Sakolb } 626*c6402783Sakolb 627*c6402783Sakolb /* Read lgroup_table and copy it to lwsd_lgrp_tbl */ 628*c6402783Sakolb if (mdb_lookup_by_name("lgrp_table", &sym) == -1) { 629*c6402783Sakolb mdb_warn("failed to find 'lgrp_table'"); 630*c6402783Sakolb return (WALK_ERR); 631*c6402783Sakolb } 632*c6402783Sakolb 633*c6402783Sakolb /* Get number of valid entries in lgrp_table */ 634*c6402783Sakolb if (sym.st_size < nlgrps * sizeof (lgrp_t *)) { 635*c6402783Sakolb mdb_warn("lgrp_table size inconsistent with lgrp_alloc_max"); 636*c6402783Sakolb return (WALK_ERR); 637*c6402783Sakolb } 638*c6402783Sakolb 639*c6402783Sakolb lwsd->lwsd_lgrp_tbl = mdb_alloc(sym.st_size, UM_SLEEP | UM_GC); 640*c6402783Sakolb lwsd->lswd_nlgrps = nlgrps; 641*c6402783Sakolb 642*c6402783Sakolb if (mdb_readsym(lwsd->lwsd_lgrp_tbl, nlgrps * sizeof (lgrp_t *), 643*c6402783Sakolb "lgrp_table") == -1) { 644*c6402783Sakolb mdb_warn("unable to read lgrp_table"); 645*c6402783Sakolb return (WALK_ERR); 646*c6402783Sakolb } 647*c6402783Sakolb 648*c6402783Sakolb wsp->walk_data = lwsd; 649*c6402783Sakolb 650*c6402783Sakolb /* Save the first lgroup from the set and remove it from the set */ 651*c6402783Sakolb wsp->walk_addr = lwsd->lwsd_lgrp_tbl[id]; 652*c6402783Sakolb lwsd->lwsd_set = set & ~(1 << id); 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate return (WALK_NEXT); 6557c478bd9Sstevel@tonic-gate } 656*c6402783Sakolb 657*c6402783Sakolb /* 658*c6402783Sakolb * Get current lgroup and advance the lgroup to the next one in the lwsd_set. 659*c6402783Sakolb */ 660*c6402783Sakolb int 661*c6402783Sakolb lgrp_set_walk_step(mdb_walk_state_t *wsp) 662*c6402783Sakolb { 663*c6402783Sakolb lgrp_id_t id = 0; 664*c6402783Sakolb lgrp_set_walk_data_t *lwsd = wsp->walk_data; 665*c6402783Sakolb int status = lgrp_walk_step_common(wsp); 666*c6402783Sakolb 667*c6402783Sakolb if (status == WALK_NEXT) { 668*c6402783Sakolb id = lgrp_set_get_first(lwsd->lwsd_set, lwsd->lswd_nlgrps); 669*c6402783Sakolb if (id == LGRP_NONE) { 670*c6402783Sakolb status = WALK_DONE; 671*c6402783Sakolb } else { 672*c6402783Sakolb /* Move to the next lgroup in the set */ 673*c6402783Sakolb wsp->walk_addr = lwsd->lwsd_lgrp_tbl[id]; 674*c6402783Sakolb 675*c6402783Sakolb /* Remove id from the set */ 676*c6402783Sakolb lwsd->lwsd_set = lwsd->lwsd_set & ~(1 << id); 677*c6402783Sakolb } 678*c6402783Sakolb } 679*c6402783Sakolb 680*c6402783Sakolb return (status); 681*c6402783Sakolb } 682*c6402783Sakolb 683*c6402783Sakolb /* 684*c6402783Sakolb * Initialize resource walker for a given lgroup and resource. The lgroup 685*c6402783Sakolb * address is specified in walk_addr. 686*c6402783Sakolb */ 687*c6402783Sakolb static int 688*c6402783Sakolb lgrp_rsrc_walk_init(mdb_walk_state_t *wsp, int resource) 689*c6402783Sakolb { 690*c6402783Sakolb lgrp_t lgrp; 691*c6402783Sakolb 692*c6402783Sakolb if (mdb_vread(&lgrp, sizeof (struct lgrp), wsp->walk_addr) == -1) { 693*c6402783Sakolb mdb_warn("couldn't read 'lgrp' at %p", wsp->walk_addr); 694*c6402783Sakolb return (WALK_ERR); 695*c6402783Sakolb } 696*c6402783Sakolb 697*c6402783Sakolb return (lgrp_set_walk_init(wsp, lgrp.lgrp_set[resource])); 698*c6402783Sakolb } 699*c6402783Sakolb 700*c6402783Sakolb /* 701*c6402783Sakolb * Initialize CPU resource walker 702*c6402783Sakolb */ 703*c6402783Sakolb int 704*c6402783Sakolb lgrp_rsrc_cpu_walk_init(mdb_walk_state_t *wsp) 705*c6402783Sakolb { 706*c6402783Sakolb return (lgrp_rsrc_walk_init(wsp, LGRP_RSRC_CPU)); 707*c6402783Sakolb } 708*c6402783Sakolb 709*c6402783Sakolb /* 710*c6402783Sakolb * Initialize memory resource walker 711*c6402783Sakolb */ 712*c6402783Sakolb int 713*c6402783Sakolb lgrp_rsrc_mem_walk_init(mdb_walk_state_t *wsp) 714*c6402783Sakolb { 715*c6402783Sakolb return (lgrp_rsrc_walk_init(wsp, LGRP_RSRC_MEM)); 716*c6402783Sakolb } 717*c6402783Sakolb 718*c6402783Sakolb /* 719*c6402783Sakolb * Display bitmap as a list of integers 720*c6402783Sakolb */ 721*c6402783Sakolb /* ARGSUSED */ 722*c6402783Sakolb int 723*c6402783Sakolb lgrp_set(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 724*c6402783Sakolb { 725*c6402783Sakolb uint64_t set = (uint64_t)addr; 726*c6402783Sakolb uint64_t mask = 1; 727*c6402783Sakolb int i = 0; 728*c6402783Sakolb 729*c6402783Sakolb if (!(flags & DCMD_ADDRSPEC)) { 730*c6402783Sakolb return (DCMD_USAGE); 731*c6402783Sakolb } 732*c6402783Sakolb 733*c6402783Sakolb if (set == 0) 734*c6402783Sakolb return (DCMD_OK); 735*c6402783Sakolb 736*c6402783Sakolb for (; set != (uint64_t)0; i++, mask <<= 1) { 737*c6402783Sakolb if (set & mask) { 738*c6402783Sakolb mdb_printf("%d ", i); 739*c6402783Sakolb set &= ~mask; 740*c6402783Sakolb } 741*c6402783Sakolb } 742*c6402783Sakolb mdb_printf("\n"); 743*c6402783Sakolb return (DCMD_OK); 744*c6402783Sakolb } 745