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 2002 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 30*0Sstevel@tonic-gate #include <mdb/mdb_param.h> 31*0Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 32*0Sstevel@tonic-gate #include <mdb/mdb_ks.h> 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate #include "lgrp.h" 35*0Sstevel@tonic-gate #include "cpupart_mdb.h" 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate #include <sys/cpuvar.h> 38*0Sstevel@tonic-gate #include <sys/cpupart.h> 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate /* ARGSUSED */ 41*0Sstevel@tonic-gate static int 42*0Sstevel@tonic-gate cpupart_cpulist_callback(uintptr_t addr, const void *arg, void *cb_data) 43*0Sstevel@tonic-gate { 44*0Sstevel@tonic-gate cpu_t *cpu = (cpu_t *)arg; 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate ulong_t *cpuset = cb_data; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate BT_SET(cpuset, cpu->cpu_id); 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate return (WALK_NEXT); 51*0Sstevel@tonic-gate } 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate /* ARGSUSED */ 54*0Sstevel@tonic-gate int 55*0Sstevel@tonic-gate cpupart(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 56*0Sstevel@tonic-gate { 57*0Sstevel@tonic-gate cpupart_t cpupart; 58*0Sstevel@tonic-gate int cpusetsize; 59*0Sstevel@tonic-gate int _ncpu; 60*0Sstevel@tonic-gate ulong_t *cpuset; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate if (argc != 0) 63*0Sstevel@tonic-gate return (DCMD_USAGE); 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 66*0Sstevel@tonic-gate if (mdb_walk_dcmd("cpupart_walk", "cpupart", argc, argv) 67*0Sstevel@tonic-gate == -1) { 68*0Sstevel@tonic-gate mdb_warn("can't walk 'cpupart'"); 69*0Sstevel@tonic-gate return (DCMD_ERR); 70*0Sstevel@tonic-gate } 71*0Sstevel@tonic-gate return (DCMD_OK); 72*0Sstevel@tonic-gate } 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 76*0Sstevel@tonic-gate mdb_printf("%3s %?s %4s %4s\n", 77*0Sstevel@tonic-gate "ID", 78*0Sstevel@tonic-gate "ADDR", 79*0Sstevel@tonic-gate "#CPU", 80*0Sstevel@tonic-gate "CPUS"); 81*0Sstevel@tonic-gate } 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), addr) == -1) { 84*0Sstevel@tonic-gate mdb_warn("unable to read 'cpupart_t' at %p", addr); 85*0Sstevel@tonic-gate return (DCMD_ERR); 86*0Sstevel@tonic-gate } 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate mdb_printf("%3d %?p %4d ", 89*0Sstevel@tonic-gate cpupart.cp_id, 90*0Sstevel@tonic-gate addr, 91*0Sstevel@tonic-gate cpupart.cp_ncpus); 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate if (cpupart.cp_ncpus == 0) { 94*0Sstevel@tonic-gate mdb_printf("\n"); 95*0Sstevel@tonic-gate return (DCMD_OK); 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate /* 99*0Sstevel@tonic-gate * figure out what cpus we've got 100*0Sstevel@tonic-gate */ 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate if (mdb_readsym(&_ncpu, sizeof (int), "_ncpu") == -1) { 104*0Sstevel@tonic-gate mdb_warn("symbol '_ncpu' not found"); 105*0Sstevel@tonic-gate return (DCMD_ERR); 106*0Sstevel@tonic-gate } 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate /* 109*0Sstevel@tonic-gate * allocate enough space for set of longs to hold cpuid bitfield 110*0Sstevel@tonic-gate */ 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate cpusetsize = BT_BITOUL(_ncpu) * sizeof (ulong_t); 113*0Sstevel@tonic-gate cpuset = mdb_zalloc(cpusetsize, UM_SLEEP | UM_GC); 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate if (mdb_pwalk("cpupart_cpulist", cpupart_cpulist_callback, cpuset, 116*0Sstevel@tonic-gate addr) == -1) { 117*0Sstevel@tonic-gate mdb_warn("unable to walk cpupart_cpulist"); 118*0Sstevel@tonic-gate return (DCMD_ERR); 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate print_cpuset_range(cpuset, cpusetsize/sizeof (ulong_t), 0); 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate mdb_printf("\n"); 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate return (DCMD_OK); 126*0Sstevel@tonic-gate } 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate typedef struct cpupart_cpulist_walk { 129*0Sstevel@tonic-gate uintptr_t ccw_firstcpu; 130*0Sstevel@tonic-gate int ccw_cpusleft; 131*0Sstevel@tonic-gate } cpupart_cpulist_walk_t; 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate int 134*0Sstevel@tonic-gate cpupart_cpulist_walk_init(mdb_walk_state_t *wsp) 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate cpupart_cpulist_walk_t *ccw; 137*0Sstevel@tonic-gate cpupart_t cpupart; 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate ccw = mdb_alloc(sizeof (cpupart_cpulist_walk_t), UM_SLEEP | UM_GC); 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), wsp->walk_addr) == -1) { 142*0Sstevel@tonic-gate mdb_warn("couldn't read 'cpupart' at %p", wsp->walk_addr); 143*0Sstevel@tonic-gate return (WALK_ERR); 144*0Sstevel@tonic-gate } 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate ccw->ccw_firstcpu = (uintptr_t)cpupart.cp_cpulist; 147*0Sstevel@tonic-gate ccw->ccw_cpusleft = cpupart.cp_ncpus; 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate wsp->walk_data = ccw; 150*0Sstevel@tonic-gate wsp->walk_addr = ccw->ccw_firstcpu; 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate return (WALK_NEXT); 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate int 156*0Sstevel@tonic-gate cpupart_cpulist_walk_step(mdb_walk_state_t *wsp) 157*0Sstevel@tonic-gate { 158*0Sstevel@tonic-gate cpupart_cpulist_walk_t *ccw = (cpupart_cpulist_walk_t *) 159*0Sstevel@tonic-gate wsp->walk_data; 160*0Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 161*0Sstevel@tonic-gate cpu_t cpu; 162*0Sstevel@tonic-gate int status; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate if (mdb_vread(&cpu, sizeof (cpu_t), addr) == -1) { 165*0Sstevel@tonic-gate mdb_warn("couldn't read 'cpupart' at %p", addr); 166*0Sstevel@tonic-gate return (WALK_ERR); 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate status = wsp->walk_callback(addr, &cpu, wsp->walk_cbdata); 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate if (status != WALK_NEXT) 172*0Sstevel@tonic-gate return (status); 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate addr = (uintptr_t)cpu.cpu_next_part; 175*0Sstevel@tonic-gate wsp->walk_addr = addr; 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate ccw->ccw_cpusleft--; 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate if (ccw->ccw_cpusleft < 0) { 180*0Sstevel@tonic-gate mdb_warn("cpu count doesn't match cpupart list"); 181*0Sstevel@tonic-gate return (WALK_ERR); 182*0Sstevel@tonic-gate } 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate if (ccw->ccw_firstcpu == addr) { 185*0Sstevel@tonic-gate if (ccw->ccw_cpusleft != 0) { 186*0Sstevel@tonic-gate mdb_warn("cpu count doesn't match cpupart list"); 187*0Sstevel@tonic-gate return (WALK_ERR); 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate return (WALK_DONE); 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate return (WALK_NEXT); 193*0Sstevel@tonic-gate } 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate int 196*0Sstevel@tonic-gate cpupart_walk_init(mdb_walk_state_t *wsp) 197*0Sstevel@tonic-gate { 198*0Sstevel@tonic-gate GElf_Sym sym; 199*0Sstevel@tonic-gate uintptr_t addr; 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate if (mdb_lookup_by_name("cp_default", &sym) == -1) { 202*0Sstevel@tonic-gate mdb_warn("failed to find 'cp_default'\n"); 203*0Sstevel@tonic-gate return (WALK_ERR); 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate addr = (uintptr_t)sym.st_value; 207*0Sstevel@tonic-gate wsp->walk_data = (void *)addr; 208*0Sstevel@tonic-gate wsp->walk_addr = addr; 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate return (WALK_NEXT); 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate int 214*0Sstevel@tonic-gate cpupart_walk_step(mdb_walk_state_t *wsp) 215*0Sstevel@tonic-gate { 216*0Sstevel@tonic-gate cpupart_t cpupart; 217*0Sstevel@tonic-gate int status; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), 220*0Sstevel@tonic-gate wsp->walk_addr) == -1) { 221*0Sstevel@tonic-gate mdb_warn("unable to read cpupart at %p", 222*0Sstevel@tonic-gate wsp->walk_addr); 223*0Sstevel@tonic-gate return (WALK_ERR); 224*0Sstevel@tonic-gate } 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &cpupart, 227*0Sstevel@tonic-gate wsp->walk_cbdata); 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate if (status != WALK_NEXT) 230*0Sstevel@tonic-gate return (status); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)cpupart.cp_next; 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate if (wsp->walk_addr == (uintptr_t)wsp->walk_data) 235*0Sstevel@tonic-gate return (WALK_DONE); 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate return (WALK_NEXT); 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate } 240