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 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*f5533078Smishra * Copyright 2005 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 307c478bd9Sstevel@tonic-gate #include <mdb/mdb_param.h> 317c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 327c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include "lgrp.h" 357c478bd9Sstevel@tonic-gate #include "cpupart_mdb.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h> 387c478bd9Sstevel@tonic-gate #include <sys/cpupart.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* ARGSUSED */ 417c478bd9Sstevel@tonic-gate static int 427c478bd9Sstevel@tonic-gate cpupart_cpulist_callback(uintptr_t addr, const void *arg, void *cb_data) 437c478bd9Sstevel@tonic-gate { 447c478bd9Sstevel@tonic-gate cpu_t *cpu = (cpu_t *)arg; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate ulong_t *cpuset = cb_data; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate BT_SET(cpuset, cpu->cpu_id); 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate return (WALK_NEXT); 517c478bd9Sstevel@tonic-gate } 527c478bd9Sstevel@tonic-gate 53*f5533078Smishra #define CPUPART_IDWIDTH 3 54*f5533078Smishra 55*f5533078Smishra #ifdef _LP64 56*f5533078Smishra #define CPUPART_CPUWIDTH 21 57*f5533078Smishra #if defined(__amd64) 58*f5533078Smishra #define CPUPART_TWIDTH 16 59*f5533078Smishra #else 60*f5533078Smishra #define CPUPART_TWIDTH 11 61*f5533078Smishra #endif 62*f5533078Smishra #else 63*f5533078Smishra #define CPUPART_CPUWIDTH 13 64*f5533078Smishra #define CPUPART_TWIDTH 8 65*f5533078Smishra #endif 66*f5533078Smishra 67*f5533078Smishra 68*f5533078Smishra #define CPUPART_THRDELT (CPUPART_IDWIDTH + CPUPART_CPUWIDTH) 69*f5533078Smishra #define CPUPART_INDENT mdb_printf("%*s", CPUPART_THRDELT, "") 70*f5533078Smishra 71*f5533078Smishra int 72*f5533078Smishra cpupart_disp_threads(disp_t *disp) 73*f5533078Smishra { 74*f5533078Smishra dispq_t *dq; 75*f5533078Smishra int i, npri = disp->disp_npri; 76*f5533078Smishra proc_t p; 77*f5533078Smishra kthread_t t; 78*f5533078Smishra 79*f5533078Smishra dq = mdb_alloc(sizeof (dispq_t) * npri, UM_SLEEP | UM_GC); 80*f5533078Smishra 81*f5533078Smishra if (mdb_vread(dq, sizeof (dispq_t) * npri, 82*f5533078Smishra (uintptr_t)disp->disp_q) == -1) { 83*f5533078Smishra mdb_warn("failed to read dispq_t at %p", disp->disp_q); 84*f5533078Smishra return (DCMD_ERR); 85*f5533078Smishra } 86*f5533078Smishra 87*f5533078Smishra CPUPART_INDENT; 88*f5533078Smishra mdb_printf("|\n"); 89*f5533078Smishra CPUPART_INDENT; 90*f5533078Smishra mdb_printf("+--> %3s %-*s %s\n", "PRI", CPUPART_TWIDTH, "THREAD", 91*f5533078Smishra "PROC"); 92*f5533078Smishra 93*f5533078Smishra for (i = npri - 1; i >= 0; i--) { 94*f5533078Smishra uintptr_t taddr = (uintptr_t)dq[i].dq_first; 95*f5533078Smishra 96*f5533078Smishra while (taddr != NULL) { 97*f5533078Smishra if (mdb_vread(&t, sizeof (t), taddr) == -1) { 98*f5533078Smishra mdb_warn("failed to read kthread_t at %p", 99*f5533078Smishra taddr); 100*f5533078Smishra return (DCMD_ERR); 101*f5533078Smishra } 102*f5533078Smishra 103*f5533078Smishra if (mdb_vread(&p, sizeof (p), 104*f5533078Smishra (uintptr_t)t.t_procp) == -1) { 105*f5533078Smishra mdb_warn("failed to read proc_t at %p", 106*f5533078Smishra t.t_procp); 107*f5533078Smishra return (DCMD_ERR); 108*f5533078Smishra } 109*f5533078Smishra 110*f5533078Smishra CPUPART_INDENT; 111*f5533078Smishra mdb_printf("%9d %0*p %s\n", t.t_pri, CPUPART_TWIDTH, 112*f5533078Smishra taddr, p.p_user.u_comm); 113*f5533078Smishra 114*f5533078Smishra taddr = (uintptr_t)t.t_link; 115*f5533078Smishra } 116*f5533078Smishra } 117*f5533078Smishra 118*f5533078Smishra return (DCMD_OK); 119*f5533078Smishra } 120*f5533078Smishra 1217c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1227c478bd9Sstevel@tonic-gate int 1237c478bd9Sstevel@tonic-gate cpupart(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1247c478bd9Sstevel@tonic-gate { 1257c478bd9Sstevel@tonic-gate cpupart_t cpupart; 1267c478bd9Sstevel@tonic-gate int cpusetsize; 1277c478bd9Sstevel@tonic-gate int _ncpu; 1287c478bd9Sstevel@tonic-gate ulong_t *cpuset; 129*f5533078Smishra uint_t verbose = FALSE; 1307c478bd9Sstevel@tonic-gate 131*f5533078Smishra if (mdb_getopts(argc, argv, 132*f5533078Smishra 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) 1337c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 1367c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("cpupart_walk", "cpupart", argc, argv) 1377c478bd9Sstevel@tonic-gate == -1) { 1387c478bd9Sstevel@tonic-gate mdb_warn("can't walk 'cpupart'"); 1397c478bd9Sstevel@tonic-gate return (DCMD_ERR); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate return (DCMD_OK); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 145*f5533078Smishra mdb_printf("%3s %?s %4s %4s %4s\n", 1467c478bd9Sstevel@tonic-gate "ID", 1477c478bd9Sstevel@tonic-gate "ADDR", 148*f5533078Smishra "NRUN", 1497c478bd9Sstevel@tonic-gate "#CPU", 1507c478bd9Sstevel@tonic-gate "CPUS"); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), addr) == -1) { 1547c478bd9Sstevel@tonic-gate mdb_warn("unable to read 'cpupart_t' at %p", addr); 1557c478bd9Sstevel@tonic-gate return (DCMD_ERR); 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate 158*f5533078Smishra mdb_printf("%3d %?p %4d %4d ", 1597c478bd9Sstevel@tonic-gate cpupart.cp_id, 1607c478bd9Sstevel@tonic-gate addr, 161*f5533078Smishra cpupart.cp_kp_queue.disp_nrunnable, 1627c478bd9Sstevel@tonic-gate cpupart.cp_ncpus); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate if (cpupart.cp_ncpus == 0) { 1657c478bd9Sstevel@tonic-gate mdb_printf("\n"); 1667c478bd9Sstevel@tonic-gate return (DCMD_OK); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * figure out what cpus we've got 1717c478bd9Sstevel@tonic-gate */ 1727c478bd9Sstevel@tonic-gate if (mdb_readsym(&_ncpu, sizeof (int), "_ncpu") == -1) { 1737c478bd9Sstevel@tonic-gate mdb_warn("symbol '_ncpu' not found"); 1747c478bd9Sstevel@tonic-gate return (DCMD_ERR); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate /* 1787c478bd9Sstevel@tonic-gate * allocate enough space for set of longs to hold cpuid bitfield 1797c478bd9Sstevel@tonic-gate */ 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate cpusetsize = BT_BITOUL(_ncpu) * sizeof (ulong_t); 1827c478bd9Sstevel@tonic-gate cpuset = mdb_zalloc(cpusetsize, UM_SLEEP | UM_GC); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (mdb_pwalk("cpupart_cpulist", cpupart_cpulist_callback, cpuset, 1857c478bd9Sstevel@tonic-gate addr) == -1) { 1867c478bd9Sstevel@tonic-gate mdb_warn("unable to walk cpupart_cpulist"); 1877c478bd9Sstevel@tonic-gate return (DCMD_ERR); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate print_cpuset_range(cpuset, cpusetsize/sizeof (ulong_t), 0); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate mdb_printf("\n"); 193*f5533078Smishra /* 194*f5533078Smishra * If there are any threads on kp queue and -v is specified 195*f5533078Smishra */ 196*f5533078Smishra if (verbose && cpupart.cp_kp_queue.disp_nrunnable) { 197*f5533078Smishra if (cpupart_disp_threads(&cpupart.cp_kp_queue) != DCMD_OK) 198*f5533078Smishra return (DCMD_ERR); 199*f5533078Smishra } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate return (DCMD_OK); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate typedef struct cpupart_cpulist_walk { 2057c478bd9Sstevel@tonic-gate uintptr_t ccw_firstcpu; 2067c478bd9Sstevel@tonic-gate int ccw_cpusleft; 2077c478bd9Sstevel@tonic-gate } cpupart_cpulist_walk_t; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate int 2107c478bd9Sstevel@tonic-gate cpupart_cpulist_walk_init(mdb_walk_state_t *wsp) 2117c478bd9Sstevel@tonic-gate { 2127c478bd9Sstevel@tonic-gate cpupart_cpulist_walk_t *ccw; 2137c478bd9Sstevel@tonic-gate cpupart_t cpupart; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate ccw = mdb_alloc(sizeof (cpupart_cpulist_walk_t), UM_SLEEP | UM_GC); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), wsp->walk_addr) == -1) { 2187c478bd9Sstevel@tonic-gate mdb_warn("couldn't read 'cpupart' at %p", wsp->walk_addr); 2197c478bd9Sstevel@tonic-gate return (WALK_ERR); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate ccw->ccw_firstcpu = (uintptr_t)cpupart.cp_cpulist; 2237c478bd9Sstevel@tonic-gate ccw->ccw_cpusleft = cpupart.cp_ncpus; 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate wsp->walk_data = ccw; 2267c478bd9Sstevel@tonic-gate wsp->walk_addr = ccw->ccw_firstcpu; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate return (WALK_NEXT); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate int 2327c478bd9Sstevel@tonic-gate cpupart_cpulist_walk_step(mdb_walk_state_t *wsp) 2337c478bd9Sstevel@tonic-gate { 2347c478bd9Sstevel@tonic-gate cpupart_cpulist_walk_t *ccw = (cpupart_cpulist_walk_t *) 2357c478bd9Sstevel@tonic-gate wsp->walk_data; 2367c478bd9Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 2377c478bd9Sstevel@tonic-gate cpu_t cpu; 2387c478bd9Sstevel@tonic-gate int status; 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate if (mdb_vread(&cpu, sizeof (cpu_t), addr) == -1) { 2417c478bd9Sstevel@tonic-gate mdb_warn("couldn't read 'cpupart' at %p", addr); 2427c478bd9Sstevel@tonic-gate return (WALK_ERR); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate status = wsp->walk_callback(addr, &cpu, wsp->walk_cbdata); 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate if (status != WALK_NEXT) 2487c478bd9Sstevel@tonic-gate return (status); 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate addr = (uintptr_t)cpu.cpu_next_part; 2517c478bd9Sstevel@tonic-gate wsp->walk_addr = addr; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate ccw->ccw_cpusleft--; 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate if (ccw->ccw_cpusleft < 0) { 2567c478bd9Sstevel@tonic-gate mdb_warn("cpu count doesn't match cpupart list"); 2577c478bd9Sstevel@tonic-gate return (WALK_ERR); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate if (ccw->ccw_firstcpu == addr) { 2617c478bd9Sstevel@tonic-gate if (ccw->ccw_cpusleft != 0) { 2627c478bd9Sstevel@tonic-gate mdb_warn("cpu count doesn't match cpupart list"); 2637c478bd9Sstevel@tonic-gate return (WALK_ERR); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate return (WALK_DONE); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate return (WALK_NEXT); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate int 2727c478bd9Sstevel@tonic-gate cpupart_walk_init(mdb_walk_state_t *wsp) 2737c478bd9Sstevel@tonic-gate { 2747c478bd9Sstevel@tonic-gate GElf_Sym sym; 2757c478bd9Sstevel@tonic-gate uintptr_t addr; 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate if (mdb_lookup_by_name("cp_default", &sym) == -1) { 2787c478bd9Sstevel@tonic-gate mdb_warn("failed to find 'cp_default'\n"); 2797c478bd9Sstevel@tonic-gate return (WALK_ERR); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate addr = (uintptr_t)sym.st_value; 2837c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)addr; 2847c478bd9Sstevel@tonic-gate wsp->walk_addr = addr; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate return (WALK_NEXT); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate int 2907c478bd9Sstevel@tonic-gate cpupart_walk_step(mdb_walk_state_t *wsp) 2917c478bd9Sstevel@tonic-gate { 2927c478bd9Sstevel@tonic-gate cpupart_t cpupart; 2937c478bd9Sstevel@tonic-gate int status; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate if (mdb_vread(&cpupart, sizeof (cpupart_t), 2967c478bd9Sstevel@tonic-gate wsp->walk_addr) == -1) { 2977c478bd9Sstevel@tonic-gate mdb_warn("unable to read cpupart at %p", 2987c478bd9Sstevel@tonic-gate wsp->walk_addr); 2997c478bd9Sstevel@tonic-gate return (WALK_ERR); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &cpupart, 3037c478bd9Sstevel@tonic-gate wsp->walk_cbdata); 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate if (status != WALK_NEXT) 3067c478bd9Sstevel@tonic-gate return (status); 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)cpupart.cp_next; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate if (wsp->walk_addr == (uintptr_t)wsp->walk_data) 3117c478bd9Sstevel@tonic-gate return (WALK_DONE); 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate return (WALK_NEXT); 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate } 316