1*10673SKrishnendu.Sadhukhan@Sun.COM /* 2*10673SKrishnendu.Sadhukhan@Sun.COM * CDDL HEADER START 3*10673SKrishnendu.Sadhukhan@Sun.COM * 4*10673SKrishnendu.Sadhukhan@Sun.COM * The contents of this file are subject to the terms of the 5*10673SKrishnendu.Sadhukhan@Sun.COM * Common Development and Distribution License (the "License"). 6*10673SKrishnendu.Sadhukhan@Sun.COM * You may not use this file except in compliance with the License. 7*10673SKrishnendu.Sadhukhan@Sun.COM * 8*10673SKrishnendu.Sadhukhan@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10673SKrishnendu.Sadhukhan@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*10673SKrishnendu.Sadhukhan@Sun.COM * See the License for the specific language governing permissions 11*10673SKrishnendu.Sadhukhan@Sun.COM * and limitations under the License. 12*10673SKrishnendu.Sadhukhan@Sun.COM * 13*10673SKrishnendu.Sadhukhan@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*10673SKrishnendu.Sadhukhan@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10673SKrishnendu.Sadhukhan@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*10673SKrishnendu.Sadhukhan@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*10673SKrishnendu.Sadhukhan@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*10673SKrishnendu.Sadhukhan@Sun.COM * 19*10673SKrishnendu.Sadhukhan@Sun.COM * CDDL HEADER END 20*10673SKrishnendu.Sadhukhan@Sun.COM */ 21*10673SKrishnendu.Sadhukhan@Sun.COM /* 22*10673SKrishnendu.Sadhukhan@Sun.COM * Copyright (c) 2008-2009, Intel Corporation. 23*10673SKrishnendu.Sadhukhan@Sun.COM * All Rights Reserved. 24*10673SKrishnendu.Sadhukhan@Sun.COM */ 25*10673SKrishnendu.Sadhukhan@Sun.COM 26*10673SKrishnendu.Sadhukhan@Sun.COM #include <unistd.h> 27*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdio.h> 28*10673SKrishnendu.Sadhukhan@Sun.COM #include <dtrace.h> 29*10673SKrishnendu.Sadhukhan@Sun.COM #include <string.h> 30*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdlib.h> 31*10673SKrishnendu.Sadhukhan@Sun.COM #include <memory.h> 32*10673SKrishnendu.Sadhukhan@Sun.COM #include <limits.h> 33*10673SKrishnendu.Sadhukhan@Sun.COM 34*10673SKrishnendu.Sadhukhan@Sun.COM #include "latencytop.h" 35*10673SKrishnendu.Sadhukhan@Sun.COM 36*10673SKrishnendu.Sadhukhan@Sun.COM static dtrace_hdl_t *g_dtp = NULL; /* dtrace handle */ 37*10673SKrishnendu.Sadhukhan@Sun.COM static pid_t pid_self = -1; /* PID of our own process */ 38*10673SKrishnendu.Sadhukhan@Sun.COM 39*10673SKrishnendu.Sadhukhan@Sun.COM /* 40*10673SKrishnendu.Sadhukhan@Sun.COM * Ignore sched if sched is not tracked. 41*10673SKrishnendu.Sadhukhan@Sun.COM * Also ignore ourselves (i.e., latencytop). 42*10673SKrishnendu.Sadhukhan@Sun.COM */ 43*10673SKrishnendu.Sadhukhan@Sun.COM #define SHOULD_IGNORE(pid) \ 44*10673SKrishnendu.Sadhukhan@Sun.COM ((!g_config.lt_cfg_trace_sched && 0 == (pid)) || pid_self == (pid)) 45*10673SKrishnendu.Sadhukhan@Sun.COM 46*10673SKrishnendu.Sadhukhan@Sun.COM /* 47*10673SKrishnendu.Sadhukhan@Sun.COM * Get an integer value from dtrace record. 48*10673SKrishnendu.Sadhukhan@Sun.COM */ 49*10673SKrishnendu.Sadhukhan@Sun.COM static uint64_t 50*10673SKrishnendu.Sadhukhan@Sun.COM rec_get_value(void *a, size_t b) 51*10673SKrishnendu.Sadhukhan@Sun.COM { 52*10673SKrishnendu.Sadhukhan@Sun.COM uint64_t ret = 0; 53*10673SKrishnendu.Sadhukhan@Sun.COM 54*10673SKrishnendu.Sadhukhan@Sun.COM switch (b) { 55*10673SKrishnendu.Sadhukhan@Sun.COM case sizeof (uint64_t): 56*10673SKrishnendu.Sadhukhan@Sun.COM ret = *((uint64_t *)(a)); 57*10673SKrishnendu.Sadhukhan@Sun.COM break; 58*10673SKrishnendu.Sadhukhan@Sun.COM case sizeof (uint32_t): 59*10673SKrishnendu.Sadhukhan@Sun.COM ret = *((uint32_t *)(a)); 60*10673SKrishnendu.Sadhukhan@Sun.COM break; 61*10673SKrishnendu.Sadhukhan@Sun.COM case sizeof (uint16_t): 62*10673SKrishnendu.Sadhukhan@Sun.COM ret = *((uint16_t *)(a)); 63*10673SKrishnendu.Sadhukhan@Sun.COM break; 64*10673SKrishnendu.Sadhukhan@Sun.COM case sizeof (uint8_t): 65*10673SKrishnendu.Sadhukhan@Sun.COM ret = *((uint8_t *)(a)); 66*10673SKrishnendu.Sadhukhan@Sun.COM break; 67*10673SKrishnendu.Sadhukhan@Sun.COM default: 68*10673SKrishnendu.Sadhukhan@Sun.COM break; 69*10673SKrishnendu.Sadhukhan@Sun.COM } 70*10673SKrishnendu.Sadhukhan@Sun.COM 71*10673SKrishnendu.Sadhukhan@Sun.COM return (ret); 72*10673SKrishnendu.Sadhukhan@Sun.COM } 73*10673SKrishnendu.Sadhukhan@Sun.COM 74*10673SKrishnendu.Sadhukhan@Sun.COM /* 75*10673SKrishnendu.Sadhukhan@Sun.COM * Callback to process aggregation lt_call_* (related to on/off cpu 76*10673SKrishnendu.Sadhukhan@Sun.COM * activities) in the snapshot. 77*10673SKrishnendu.Sadhukhan@Sun.COM */ 78*10673SKrishnendu.Sadhukhan@Sun.COM static int 79*10673SKrishnendu.Sadhukhan@Sun.COM aggwalk_call(const dtrace_aggdata_t *data, lt_stat_type_t stat_type) 80*10673SKrishnendu.Sadhukhan@Sun.COM { 81*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_aggdesc_t *aggdesc = data->dtada_desc; 82*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_syminfo_t dts; 83*10673SKrishnendu.Sadhukhan@Sun.COM GElf_Sym sym; 84*10673SKrishnendu.Sadhukhan@Sun.COM caddr_t addr; 85*10673SKrishnendu.Sadhukhan@Sun.COM pid_t pid; 86*10673SKrishnendu.Sadhukhan@Sun.COM id_t tid; 87*10673SKrishnendu.Sadhukhan@Sun.COM unsigned int stack_depth; 88*10673SKrishnendu.Sadhukhan@Sun.COM unsigned int pc_size; 89*10673SKrishnendu.Sadhukhan@Sun.COM uint64_t pc; 90*10673SKrishnendu.Sadhukhan@Sun.COM uint64_t agg_value; 91*10673SKrishnendu.Sadhukhan@Sun.COM char *ptr = NULL; 92*10673SKrishnendu.Sadhukhan@Sun.COM char *buffer = NULL; 93*10673SKrishnendu.Sadhukhan@Sun.COM int ptrsize; 94*10673SKrishnendu.Sadhukhan@Sun.COM unsigned int buffersize; 95*10673SKrishnendu.Sadhukhan@Sun.COM char *tag = NULL; 96*10673SKrishnendu.Sadhukhan@Sun.COM unsigned int priority; 97*10673SKrishnendu.Sadhukhan@Sun.COM enum { REC_PID = 1, REC_TID, REC_STACK, REC_TAG, REC_PRIO, REC_AGG, 98*10673SKrishnendu.Sadhukhan@Sun.COM NREC }; 99*10673SKrishnendu.Sadhukhan@Sun.COM 100*10673SKrishnendu.Sadhukhan@Sun.COM /* Check action type */ 101*10673SKrishnendu.Sadhukhan@Sun.COM if ((aggdesc->dtagd_nrecs < NREC) || 102*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_PID].dtrd_action != DTRACEACT_DIFEXPR) || 103*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_TID].dtrd_action != DTRACEACT_DIFEXPR) || 104*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_TAG].dtrd_action != DTRACEACT_DIFEXPR) || 105*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_PRIO].dtrd_action != DTRACEACT_DIFEXPR) || 106*10673SKrishnendu.Sadhukhan@Sun.COM (!DTRACEACT_ISAGG(aggdesc->dtagd_rec[REC_AGG].dtrd_action)) || 107*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_STACK].dtrd_action != DTRACEACT_STACK)) { 108*10673SKrishnendu.Sadhukhan@Sun.COM 109*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 110*10673SKrishnendu.Sadhukhan@Sun.COM } 111*10673SKrishnendu.Sadhukhan@Sun.COM 112*10673SKrishnendu.Sadhukhan@Sun.COM pid = rec_get_value( 113*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_PID].dtrd_offset, 114*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_PID].dtrd_size); 115*10673SKrishnendu.Sadhukhan@Sun.COM 116*10673SKrishnendu.Sadhukhan@Sun.COM if (SHOULD_IGNORE(pid)) { 117*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 118*10673SKrishnendu.Sadhukhan@Sun.COM } 119*10673SKrishnendu.Sadhukhan@Sun.COM 120*10673SKrishnendu.Sadhukhan@Sun.COM tid = rec_get_value( 121*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_TID].dtrd_offset, 122*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_TID].dtrd_size); 123*10673SKrishnendu.Sadhukhan@Sun.COM 124*10673SKrishnendu.Sadhukhan@Sun.COM /* Parse stack array from dtagd_rec */ 125*10673SKrishnendu.Sadhukhan@Sun.COM stack_depth = aggdesc->dtagd_rec[REC_STACK].dtrd_arg; 126*10673SKrishnendu.Sadhukhan@Sun.COM pc_size = aggdesc->dtagd_rec[REC_STACK].dtrd_size / stack_depth; 127*10673SKrishnendu.Sadhukhan@Sun.COM addr = data->dtada_data + aggdesc->dtagd_rec[REC_STACK].dtrd_offset; 128*10673SKrishnendu.Sadhukhan@Sun.COM buffersize = (stack_depth * (2 * PATH_MAX + 2) + 1) * sizeof (char); 129*10673SKrishnendu.Sadhukhan@Sun.COM buffer = (char *)lt_malloc(buffersize); 130*10673SKrishnendu.Sadhukhan@Sun.COM ptr = buffer; 131*10673SKrishnendu.Sadhukhan@Sun.COM ptrsize = buffersize; 132*10673SKrishnendu.Sadhukhan@Sun.COM 133*10673SKrishnendu.Sadhukhan@Sun.COM /* Print the stack */ 134*10673SKrishnendu.Sadhukhan@Sun.COM while (stack_depth > 0) { 135*10673SKrishnendu.Sadhukhan@Sun.COM pc = rec_get_value(addr, pc_size); 136*10673SKrishnendu.Sadhukhan@Sun.COM 137*10673SKrishnendu.Sadhukhan@Sun.COM if (pc == 0) { 138*10673SKrishnendu.Sadhukhan@Sun.COM break; 139*10673SKrishnendu.Sadhukhan@Sun.COM } 140*10673SKrishnendu.Sadhukhan@Sun.COM 141*10673SKrishnendu.Sadhukhan@Sun.COM addr += pc_size; 142*10673SKrishnendu.Sadhukhan@Sun.COM 143*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_lookup_by_addr(g_dtp, pc, &sym, &dts) == 0) { 144*10673SKrishnendu.Sadhukhan@Sun.COM int len; 145*10673SKrishnendu.Sadhukhan@Sun.COM len = snprintf(ptr, ptrsize, 146*10673SKrishnendu.Sadhukhan@Sun.COM "%s`%s ", dts.dts_object, dts.dts_name); 147*10673SKrishnendu.Sadhukhan@Sun.COM ptrsize -= len; 148*10673SKrishnendu.Sadhukhan@Sun.COM 149*10673SKrishnendu.Sadhukhan@Sun.COM if (ptrsize <= 0) { 150*10673SKrishnendu.Sadhukhan@Sun.COM /* 151*10673SKrishnendu.Sadhukhan@Sun.COM * snprintf returns "desired" length, so 152*10673SKrishnendu.Sadhukhan@Sun.COM * reaching here means our buffer is full. 153*10673SKrishnendu.Sadhukhan@Sun.COM * Move ptr to the last byte of the buffer and 154*10673SKrishnendu.Sadhukhan@Sun.COM * break. 155*10673SKrishnendu.Sadhukhan@Sun.COM */ 156*10673SKrishnendu.Sadhukhan@Sun.COM ptr = &buffer[buffersize-1]; 157*10673SKrishnendu.Sadhukhan@Sun.COM break; 158*10673SKrishnendu.Sadhukhan@Sun.COM } else { 159*10673SKrishnendu.Sadhukhan@Sun.COM ptr += len; 160*10673SKrishnendu.Sadhukhan@Sun.COM } 161*10673SKrishnendu.Sadhukhan@Sun.COM } 162*10673SKrishnendu.Sadhukhan@Sun.COM } 163*10673SKrishnendu.Sadhukhan@Sun.COM 164*10673SKrishnendu.Sadhukhan@Sun.COM if (ptr != buffer) { 165*10673SKrishnendu.Sadhukhan@Sun.COM /* 166*10673SKrishnendu.Sadhukhan@Sun.COM * We have printed something, so it is safe to remove 167*10673SKrishnendu.Sadhukhan@Sun.COM * the last ' '. 168*10673SKrishnendu.Sadhukhan@Sun.COM */ 169*10673SKrishnendu.Sadhukhan@Sun.COM *(ptr-1) = '\0'; 170*10673SKrishnendu.Sadhukhan@Sun.COM } 171*10673SKrishnendu.Sadhukhan@Sun.COM 172*10673SKrishnendu.Sadhukhan@Sun.COM tag = (char *)data->dtada_data + 173*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_TAG].dtrd_offset; 174*10673SKrishnendu.Sadhukhan@Sun.COM 175*10673SKrishnendu.Sadhukhan@Sun.COM priority = rec_get_value( 176*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_PRIO].dtrd_offset, 177*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_PRIO].dtrd_size); 178*10673SKrishnendu.Sadhukhan@Sun.COM 179*10673SKrishnendu.Sadhukhan@Sun.COM agg_value = rec_get_value( 180*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_AGG].dtrd_offset, 181*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_AGG].dtrd_size); 182*10673SKrishnendu.Sadhukhan@Sun.COM 183*10673SKrishnendu.Sadhukhan@Sun.COM lt_stat_update(pid, tid, buffer, tag, priority, stat_type, agg_value); 184*10673SKrishnendu.Sadhukhan@Sun.COM 185*10673SKrishnendu.Sadhukhan@Sun.COM if (buffer != NULL) { 186*10673SKrishnendu.Sadhukhan@Sun.COM free(buffer); 187*10673SKrishnendu.Sadhukhan@Sun.COM } 188*10673SKrishnendu.Sadhukhan@Sun.COM 189*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 190*10673SKrishnendu.Sadhukhan@Sun.COM } 191*10673SKrishnendu.Sadhukhan@Sun.COM 192*10673SKrishnendu.Sadhukhan@Sun.COM /* 193*10673SKrishnendu.Sadhukhan@Sun.COM * Callback to process aggregation lt_named_* (related to lock spinning etc.), 194*10673SKrishnendu.Sadhukhan@Sun.COM * in the snapshot. 195*10673SKrishnendu.Sadhukhan@Sun.COM */ 196*10673SKrishnendu.Sadhukhan@Sun.COM static int 197*10673SKrishnendu.Sadhukhan@Sun.COM aggwalk_named(const dtrace_aggdata_t *data, lt_stat_type_t stat_type) 198*10673SKrishnendu.Sadhukhan@Sun.COM { 199*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_aggdesc_t *aggdesc = data->dtada_desc; 200*10673SKrishnendu.Sadhukhan@Sun.COM pid_t pid; 201*10673SKrishnendu.Sadhukhan@Sun.COM id_t tid; 202*10673SKrishnendu.Sadhukhan@Sun.COM uint64_t agg_value; 203*10673SKrishnendu.Sadhukhan@Sun.COM int cause_id; 204*10673SKrishnendu.Sadhukhan@Sun.COM char *type = NULL; 205*10673SKrishnendu.Sadhukhan@Sun.COM enum { REC_PID = 1, REC_TID, REC_TYPE, REC_AGG, NREC }; 206*10673SKrishnendu.Sadhukhan@Sun.COM 207*10673SKrishnendu.Sadhukhan@Sun.COM /* Check action type */ 208*10673SKrishnendu.Sadhukhan@Sun.COM if ((aggdesc->dtagd_nrecs < NREC) || 209*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_PID].dtrd_action != DTRACEACT_DIFEXPR) || 210*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_TID].dtrd_action != DTRACEACT_DIFEXPR) || 211*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_TYPE].dtrd_action != DTRACEACT_DIFEXPR) || 212*10673SKrishnendu.Sadhukhan@Sun.COM (!DTRACEACT_ISAGG(aggdesc->dtagd_rec[REC_AGG].dtrd_action))) { 213*10673SKrishnendu.Sadhukhan@Sun.COM 214*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 215*10673SKrishnendu.Sadhukhan@Sun.COM } 216*10673SKrishnendu.Sadhukhan@Sun.COM 217*10673SKrishnendu.Sadhukhan@Sun.COM pid = rec_get_value( 218*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_PID].dtrd_offset, 219*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_PID].dtrd_size); 220*10673SKrishnendu.Sadhukhan@Sun.COM 221*10673SKrishnendu.Sadhukhan@Sun.COM if (SHOULD_IGNORE(pid)) { 222*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 223*10673SKrishnendu.Sadhukhan@Sun.COM } 224*10673SKrishnendu.Sadhukhan@Sun.COM 225*10673SKrishnendu.Sadhukhan@Sun.COM tid = rec_get_value( 226*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_TID].dtrd_offset, 227*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_TID].dtrd_size); 228*10673SKrishnendu.Sadhukhan@Sun.COM 229*10673SKrishnendu.Sadhukhan@Sun.COM type = (char *)data->dtada_data 230*10673SKrishnendu.Sadhukhan@Sun.COM + aggdesc->dtagd_rec[REC_TYPE].dtrd_offset; 231*10673SKrishnendu.Sadhukhan@Sun.COM cause_id = lt_table_cause_from_name(type, 1, CAUSE_FLAG_SPECIAL); 232*10673SKrishnendu.Sadhukhan@Sun.COM 233*10673SKrishnendu.Sadhukhan@Sun.COM agg_value = rec_get_value( 234*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_AGG].dtrd_offset, 235*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_AGG].dtrd_size); 236*10673SKrishnendu.Sadhukhan@Sun.COM 237*10673SKrishnendu.Sadhukhan@Sun.COM lt_stat_update_cause(pid, tid, cause_id, stat_type, agg_value); 238*10673SKrishnendu.Sadhukhan@Sun.COM 239*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 240*10673SKrishnendu.Sadhukhan@Sun.COM 241*10673SKrishnendu.Sadhukhan@Sun.COM } 242*10673SKrishnendu.Sadhukhan@Sun.COM 243*10673SKrishnendu.Sadhukhan@Sun.COM /* 244*10673SKrishnendu.Sadhukhan@Sun.COM * Callback to process aggregation lt_sync_* (related to synchronization 245*10673SKrishnendu.Sadhukhan@Sun.COM * objects), in the snapshot. 246*10673SKrishnendu.Sadhukhan@Sun.COM */ 247*10673SKrishnendu.Sadhukhan@Sun.COM static int 248*10673SKrishnendu.Sadhukhan@Sun.COM aggwalk_sync(const dtrace_aggdata_t *data, lt_stat_type_t stat_type) 249*10673SKrishnendu.Sadhukhan@Sun.COM { 250*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_aggdesc_t *aggdesc = data->dtada_desc; 251*10673SKrishnendu.Sadhukhan@Sun.COM pid_t pid; 252*10673SKrishnendu.Sadhukhan@Sun.COM id_t tid; 253*10673SKrishnendu.Sadhukhan@Sun.COM uint64_t agg_value; 254*10673SKrishnendu.Sadhukhan@Sun.COM int stype; 255*10673SKrishnendu.Sadhukhan@Sun.COM unsigned long long wchan; 256*10673SKrishnendu.Sadhukhan@Sun.COM enum { REC_PID = 1, REC_TID, REC_STYPE, REC_WCHAN, REC_AGG, NREC }; 257*10673SKrishnendu.Sadhukhan@Sun.COM 258*10673SKrishnendu.Sadhukhan@Sun.COM /* Check action type */ 259*10673SKrishnendu.Sadhukhan@Sun.COM if ((aggdesc->dtagd_nrecs < NREC) || 260*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_PID].dtrd_action != DTRACEACT_DIFEXPR) || 261*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_TID].dtrd_action != DTRACEACT_DIFEXPR) || 262*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_STYPE].dtrd_action != DTRACEACT_DIFEXPR) || 263*10673SKrishnendu.Sadhukhan@Sun.COM (aggdesc->dtagd_rec[REC_WCHAN].dtrd_action != DTRACEACT_DIFEXPR) || 264*10673SKrishnendu.Sadhukhan@Sun.COM (!DTRACEACT_ISAGG(aggdesc->dtagd_rec[REC_AGG].dtrd_action))) { 265*10673SKrishnendu.Sadhukhan@Sun.COM 266*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 267*10673SKrishnendu.Sadhukhan@Sun.COM } 268*10673SKrishnendu.Sadhukhan@Sun.COM 269*10673SKrishnendu.Sadhukhan@Sun.COM pid = rec_get_value( 270*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_PID].dtrd_offset, 271*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_PID].dtrd_size); 272*10673SKrishnendu.Sadhukhan@Sun.COM 273*10673SKrishnendu.Sadhukhan@Sun.COM if (SHOULD_IGNORE(pid)) { 274*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 275*10673SKrishnendu.Sadhukhan@Sun.COM } 276*10673SKrishnendu.Sadhukhan@Sun.COM 277*10673SKrishnendu.Sadhukhan@Sun.COM tid = rec_get_value( 278*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_TID].dtrd_offset, 279*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_TID].dtrd_size); 280*10673SKrishnendu.Sadhukhan@Sun.COM 281*10673SKrishnendu.Sadhukhan@Sun.COM stype = rec_get_value( 282*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_STYPE].dtrd_offset, 283*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_STYPE].dtrd_size); 284*10673SKrishnendu.Sadhukhan@Sun.COM 285*10673SKrishnendu.Sadhukhan@Sun.COM wchan = rec_get_value( 286*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_WCHAN].dtrd_offset, 287*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_WCHAN].dtrd_size); 288*10673SKrishnendu.Sadhukhan@Sun.COM 289*10673SKrishnendu.Sadhukhan@Sun.COM agg_value = rec_get_value( 290*10673SKrishnendu.Sadhukhan@Sun.COM data->dtada_data + aggdesc->dtagd_rec[REC_AGG].dtrd_offset, 291*10673SKrishnendu.Sadhukhan@Sun.COM aggdesc->dtagd_rec[REC_AGG].dtrd_size); 292*10673SKrishnendu.Sadhukhan@Sun.COM 293*10673SKrishnendu.Sadhukhan@Sun.COM lt_stat_update_sobj(pid, tid, stype, wchan, stat_type, agg_value); 294*10673SKrishnendu.Sadhukhan@Sun.COM 295*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 296*10673SKrishnendu.Sadhukhan@Sun.COM } 297*10673SKrishnendu.Sadhukhan@Sun.COM 298*10673SKrishnendu.Sadhukhan@Sun.COM /* 299*10673SKrishnendu.Sadhukhan@Sun.COM * Callback to process various aggregations in the snapshot. Called by 300*10673SKrishnendu.Sadhukhan@Sun.COM * different aggwalk_* functions. 301*10673SKrishnendu.Sadhukhan@Sun.COM */ 302*10673SKrishnendu.Sadhukhan@Sun.COM /* ARGSUSED */ 303*10673SKrishnendu.Sadhukhan@Sun.COM static int 304*10673SKrishnendu.Sadhukhan@Sun.COM aggwalk(const dtrace_aggdata_t *data, void *arg) 305*10673SKrishnendu.Sadhukhan@Sun.COM { 306*10673SKrishnendu.Sadhukhan@Sun.COM char *tmp; 307*10673SKrishnendu.Sadhukhan@Sun.COM char buffer[32]; 308*10673SKrishnendu.Sadhukhan@Sun.COM lt_stat_type_t stat_type; 309*10673SKrishnendu.Sadhukhan@Sun.COM int (*func)(const dtrace_aggdata_t *, lt_stat_type_t); 310*10673SKrishnendu.Sadhukhan@Sun.COM 311*10673SKrishnendu.Sadhukhan@Sun.COM (void) strncpy(buffer, data->dtada_desc->dtagd_name, sizeof (buffer)); 312*10673SKrishnendu.Sadhukhan@Sun.COM buffer[sizeof (buffer) - 1] = '\0'; 313*10673SKrishnendu.Sadhukhan@Sun.COM tmp = strtok(buffer, "_"); 314*10673SKrishnendu.Sadhukhan@Sun.COM 315*10673SKrishnendu.Sadhukhan@Sun.COM if (tmp == NULL || strcmp(tmp, "lt") != 0) { 316*10673SKrishnendu.Sadhukhan@Sun.COM goto done; 317*10673SKrishnendu.Sadhukhan@Sun.COM } 318*10673SKrishnendu.Sadhukhan@Sun.COM 319*10673SKrishnendu.Sadhukhan@Sun.COM tmp = strtok(NULL, "_"); 320*10673SKrishnendu.Sadhukhan@Sun.COM 321*10673SKrishnendu.Sadhukhan@Sun.COM if (tmp == NULL) { 322*10673SKrishnendu.Sadhukhan@Sun.COM goto done; 323*10673SKrishnendu.Sadhukhan@Sun.COM } else if (strcmp(tmp, "call") == 0) { 324*10673SKrishnendu.Sadhukhan@Sun.COM func = aggwalk_call; 325*10673SKrishnendu.Sadhukhan@Sun.COM } else if (strcmp(tmp, "named") == 0) { 326*10673SKrishnendu.Sadhukhan@Sun.COM func = aggwalk_named; 327*10673SKrishnendu.Sadhukhan@Sun.COM } else if (strcmp(tmp, "sync") == 0) { 328*10673SKrishnendu.Sadhukhan@Sun.COM func = aggwalk_sync; 329*10673SKrishnendu.Sadhukhan@Sun.COM } else { 330*10673SKrishnendu.Sadhukhan@Sun.COM goto done; 331*10673SKrishnendu.Sadhukhan@Sun.COM } 332*10673SKrishnendu.Sadhukhan@Sun.COM 333*10673SKrishnendu.Sadhukhan@Sun.COM tmp = strtok(NULL, "_"); 334*10673SKrishnendu.Sadhukhan@Sun.COM 335*10673SKrishnendu.Sadhukhan@Sun.COM if (tmp == NULL) { 336*10673SKrishnendu.Sadhukhan@Sun.COM goto done; 337*10673SKrishnendu.Sadhukhan@Sun.COM } else if (strcmp(tmp, "count") == 0) { 338*10673SKrishnendu.Sadhukhan@Sun.COM stat_type = LT_STAT_COUNT; 339*10673SKrishnendu.Sadhukhan@Sun.COM } else if (strcmp(tmp, "sum") == 0) { 340*10673SKrishnendu.Sadhukhan@Sun.COM stat_type = LT_STAT_SUM; 341*10673SKrishnendu.Sadhukhan@Sun.COM } else if (strcmp(tmp, "max") == 0) { 342*10673SKrishnendu.Sadhukhan@Sun.COM stat_type = LT_STAT_MAX; 343*10673SKrishnendu.Sadhukhan@Sun.COM } else { 344*10673SKrishnendu.Sadhukhan@Sun.COM goto done; 345*10673SKrishnendu.Sadhukhan@Sun.COM } 346*10673SKrishnendu.Sadhukhan@Sun.COM 347*10673SKrishnendu.Sadhukhan@Sun.COM (void) func(data, stat_type); 348*10673SKrishnendu.Sadhukhan@Sun.COM 349*10673SKrishnendu.Sadhukhan@Sun.COM done: 350*10673SKrishnendu.Sadhukhan@Sun.COM /* We have our data, so remove it from DTrace now */ 351*10673SKrishnendu.Sadhukhan@Sun.COM return (DTRACE_AGGWALK_REMOVE); 352*10673SKrishnendu.Sadhukhan@Sun.COM } 353*10673SKrishnendu.Sadhukhan@Sun.COM 354*10673SKrishnendu.Sadhukhan@Sun.COM /* 355*10673SKrishnendu.Sadhukhan@Sun.COM * Callback to handle event caused by DTrace dropping data. 356*10673SKrishnendu.Sadhukhan@Sun.COM */ 357*10673SKrishnendu.Sadhukhan@Sun.COM /*ARGSUSED*/ 358*10673SKrishnendu.Sadhukhan@Sun.COM static int 359*10673SKrishnendu.Sadhukhan@Sun.COM drop_handler(const dtrace_dropdata_t *data, void *user) 360*10673SKrishnendu.Sadhukhan@Sun.COM { 361*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Drop: %s\n", data->dtdda_msg); 362*10673SKrishnendu.Sadhukhan@Sun.COM 363*10673SKrishnendu.Sadhukhan@Sun.COM /* Pretend nothing happened, so just continue */ 364*10673SKrishnendu.Sadhukhan@Sun.COM return (DTRACE_HANDLE_OK); 365*10673SKrishnendu.Sadhukhan@Sun.COM } 366*10673SKrishnendu.Sadhukhan@Sun.COM 367*10673SKrishnendu.Sadhukhan@Sun.COM #ifndef EMBED_CONFIGS 368*10673SKrishnendu.Sadhukhan@Sun.COM /* 369*10673SKrishnendu.Sadhukhan@Sun.COM * Copy the content from a "real" file into a temp file. 370*10673SKrishnendu.Sadhukhan@Sun.COM */ 371*10673SKrishnendu.Sadhukhan@Sun.COM static int 372*10673SKrishnendu.Sadhukhan@Sun.COM copy_tmp_file(const char *src, FILE *dst) 373*10673SKrishnendu.Sadhukhan@Sun.COM { 374*10673SKrishnendu.Sadhukhan@Sun.COM FILE *tmp = NULL; 375*10673SKrishnendu.Sadhukhan@Sun.COM char buffer[256]; 376*10673SKrishnendu.Sadhukhan@Sun.COM int bytes; 377*10673SKrishnendu.Sadhukhan@Sun.COM 378*10673SKrishnendu.Sadhukhan@Sun.COM if ((tmp = fopen(src, "r")) == NULL) { 379*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 380*10673SKrishnendu.Sadhukhan@Sun.COM } 381*10673SKrishnendu.Sadhukhan@Sun.COM 382*10673SKrishnendu.Sadhukhan@Sun.COM while ((bytes = fread(buffer, 1, sizeof (buffer), tmp)) > 0) { 383*10673SKrishnendu.Sadhukhan@Sun.COM if (fwrite(buffer, bytes, 1, dst) != 1) { 384*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 385*10673SKrishnendu.Sadhukhan@Sun.COM } 386*10673SKrishnendu.Sadhukhan@Sun.COM } 387*10673SKrishnendu.Sadhukhan@Sun.COM 388*10673SKrishnendu.Sadhukhan@Sun.COM (void) fclose(tmp); 389*10673SKrishnendu.Sadhukhan@Sun.COM 390*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 391*10673SKrishnendu.Sadhukhan@Sun.COM } 392*10673SKrishnendu.Sadhukhan@Sun.COM #endif 393*10673SKrishnendu.Sadhukhan@Sun.COM 394*10673SKrishnendu.Sadhukhan@Sun.COM /* 395*10673SKrishnendu.Sadhukhan@Sun.COM * DTrace initialization. D script starts running when this function returns. 396*10673SKrishnendu.Sadhukhan@Sun.COM */ 397*10673SKrishnendu.Sadhukhan@Sun.COM int 398*10673SKrishnendu.Sadhukhan@Sun.COM lt_dtrace_init(void) 399*10673SKrishnendu.Sadhukhan@Sun.COM { 400*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_prog_t *prog; 401*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_proginfo_t info; 402*10673SKrishnendu.Sadhukhan@Sun.COM int err; 403*10673SKrishnendu.Sadhukhan@Sun.COM FILE *fp_script = NULL; 404*10673SKrishnendu.Sadhukhan@Sun.COM 405*10673SKrishnendu.Sadhukhan@Sun.COM pid_self = getpid(); 406*10673SKrishnendu.Sadhukhan@Sun.COM 407*10673SKrishnendu.Sadhukhan@Sun.COM if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) { 408*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Cannot open dtrace library: %s\n", 409*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_errmsg(NULL, err)); 410*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 411*10673SKrishnendu.Sadhukhan@Sun.COM } 412*10673SKrishnendu.Sadhukhan@Sun.COM 413*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_handle_drop(g_dtp, &drop_handler, NULL) == -1) { 414*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Cannot install DTrace handle: %s\n", 415*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_errmsg(NULL, err)); 416*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 417*10673SKrishnendu.Sadhukhan@Sun.COM } 418*10673SKrishnendu.Sadhukhan@Sun.COM 419*10673SKrishnendu.Sadhukhan@Sun.COM if (g_config.lt_cfg_enable_filter) { 420*10673SKrishnendu.Sadhukhan@Sun.COM if ((err = dtrace_setopt(g_dtp, "define", 421*10673SKrishnendu.Sadhukhan@Sun.COM "ENABLE_FILTER")) != 0) { 422*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error( 423*10673SKrishnendu.Sadhukhan@Sun.COM "Failed to set option ENABLE_FILTER.\n"); 424*10673SKrishnendu.Sadhukhan@Sun.COM return (err); 425*10673SKrishnendu.Sadhukhan@Sun.COM } 426*10673SKrishnendu.Sadhukhan@Sun.COM } 427*10673SKrishnendu.Sadhukhan@Sun.COM 428*10673SKrishnendu.Sadhukhan@Sun.COM if (g_config.lt_cfg_trace_syncobj) { 429*10673SKrishnendu.Sadhukhan@Sun.COM if ((err = dtrace_setopt(g_dtp, "define", 430*10673SKrishnendu.Sadhukhan@Sun.COM "ENABLE_SYNCOBJ")) != 0) { 431*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error( 432*10673SKrishnendu.Sadhukhan@Sun.COM "Failed to set option ENABLE_SYNCOBJ.\n"); 433*10673SKrishnendu.Sadhukhan@Sun.COM return (err); 434*10673SKrishnendu.Sadhukhan@Sun.COM } 435*10673SKrishnendu.Sadhukhan@Sun.COM } 436*10673SKrishnendu.Sadhukhan@Sun.COM 437*10673SKrishnendu.Sadhukhan@Sun.COM if (g_config.lt_cfg_trace_sched) { 438*10673SKrishnendu.Sadhukhan@Sun.COM if ((err = dtrace_setopt(g_dtp, "define", 439*10673SKrishnendu.Sadhukhan@Sun.COM "ENABLE_SCHED")) != 0) { 440*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error( 441*10673SKrishnendu.Sadhukhan@Sun.COM "Failed to set option ENABLE_SYNCOBJ.\n"); 442*10673SKrishnendu.Sadhukhan@Sun.COM return (err); 443*10673SKrishnendu.Sadhukhan@Sun.COM } 444*10673SKrishnendu.Sadhukhan@Sun.COM } 445*10673SKrishnendu.Sadhukhan@Sun.COM 446*10673SKrishnendu.Sadhukhan@Sun.COM if (g_config.lt_cfg_low_overhead_mode) { 447*10673SKrishnendu.Sadhukhan@Sun.COM if ((err = dtrace_setopt(g_dtp, "define", 448*10673SKrishnendu.Sadhukhan@Sun.COM "ENABLE_LOW_OVERHEAD")) != 0) { 449*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error( 450*10673SKrishnendu.Sadhukhan@Sun.COM "Failed to set option ENABLE_SYNCOBJ.\n"); 451*10673SKrishnendu.Sadhukhan@Sun.COM return (err); 452*10673SKrishnendu.Sadhukhan@Sun.COM } 453*10673SKrishnendu.Sadhukhan@Sun.COM } 454*10673SKrishnendu.Sadhukhan@Sun.COM 455*10673SKrishnendu.Sadhukhan@Sun.COM /* Create a temp file; libdtrace needs it for cpp(1) */ 456*10673SKrishnendu.Sadhukhan@Sun.COM if ((fp_script = tmpfile()) == NULL) { 457*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Cannot create tmp file\n"); 458*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 459*10673SKrishnendu.Sadhukhan@Sun.COM } 460*10673SKrishnendu.Sadhukhan@Sun.COM 461*10673SKrishnendu.Sadhukhan@Sun.COM /* Copy the main D script into the temp file */ 462*10673SKrishnendu.Sadhukhan@Sun.COM #ifdef EMBED_CONFIGS 463*10673SKrishnendu.Sadhukhan@Sun.COM if (fwrite(&latencytop_d_start, 464*10673SKrishnendu.Sadhukhan@Sun.COM (size_t)(&latencytop_d_end - &latencytop_d_start), 1, fp_script) 465*10673SKrishnendu.Sadhukhan@Sun.COM != 1) { 466*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Could not copy D script, fwrite() failed\n"); 467*10673SKrishnendu.Sadhukhan@Sun.COM (void) fclose(fp_script); 468*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 469*10673SKrishnendu.Sadhukhan@Sun.COM } 470*10673SKrishnendu.Sadhukhan@Sun.COM #else 471*10673SKrishnendu.Sadhukhan@Sun.COM if (copy_tmp_file(DEFAULT_D_SCRIPT_NAME, fp_script) != 0) { 472*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Cannot open script file %s\n", 473*10673SKrishnendu.Sadhukhan@Sun.COM DEFAULT_D_SCRIPT_NAME); 474*10673SKrishnendu.Sadhukhan@Sun.COM (void) fclose(fp_script); 475*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 476*10673SKrishnendu.Sadhukhan@Sun.COM } 477*10673SKrishnendu.Sadhukhan@Sun.COM #endif /* EMBED_CONFIGS */ 478*10673SKrishnendu.Sadhukhan@Sun.COM 479*10673SKrishnendu.Sadhukhan@Sun.COM if (lt_table_append_trans(fp_script) != 0) { 480*10673SKrishnendu.Sadhukhan@Sun.COM (void) fclose(fp_script); 481*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 482*10673SKrishnendu.Sadhukhan@Sun.COM } 483*10673SKrishnendu.Sadhukhan@Sun.COM 484*10673SKrishnendu.Sadhukhan@Sun.COM (void) fseek(fp_script, 0, SEEK_SET); 485*10673SKrishnendu.Sadhukhan@Sun.COM 486*10673SKrishnendu.Sadhukhan@Sun.COM if ((prog = dtrace_program_fcompile(g_dtp, fp_script, 487*10673SKrishnendu.Sadhukhan@Sun.COM DTRACE_C_CPP, 0, NULL)) == NULL) { 488*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Failed to compile D script.\n"); 489*10673SKrishnendu.Sadhukhan@Sun.COM (void) fclose(fp_script); 490*10673SKrishnendu.Sadhukhan@Sun.COM return (dtrace_errno(g_dtp)); 491*10673SKrishnendu.Sadhukhan@Sun.COM } 492*10673SKrishnendu.Sadhukhan@Sun.COM 493*10673SKrishnendu.Sadhukhan@Sun.COM (void) fclose(fp_script); 494*10673SKrishnendu.Sadhukhan@Sun.COM 495*10673SKrishnendu.Sadhukhan@Sun.COM /* Execute the D script */ 496*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_program_exec(g_dtp, prog, &info) == -1) { 497*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Failed to enable probes.\n"); 498*10673SKrishnendu.Sadhukhan@Sun.COM return (dtrace_errno(g_dtp)); 499*10673SKrishnendu.Sadhukhan@Sun.COM } 500*10673SKrishnendu.Sadhukhan@Sun.COM 501*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_go(g_dtp) != 0) { 502*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Failed to run D script.\n"); 503*10673SKrishnendu.Sadhukhan@Sun.COM return (dtrace_errno(g_dtp)); 504*10673SKrishnendu.Sadhukhan@Sun.COM } 505*10673SKrishnendu.Sadhukhan@Sun.COM 506*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 507*10673SKrishnendu.Sadhukhan@Sun.COM } 508*10673SKrishnendu.Sadhukhan@Sun.COM 509*10673SKrishnendu.Sadhukhan@Sun.COM /* 510*10673SKrishnendu.Sadhukhan@Sun.COM * Worker function to move aggregate data to user space. Called periodically 511*10673SKrishnendu.Sadhukhan@Sun.COM * to prevent the kernel from running out of memory. 512*10673SKrishnendu.Sadhukhan@Sun.COM */ 513*10673SKrishnendu.Sadhukhan@Sun.COM int 514*10673SKrishnendu.Sadhukhan@Sun.COM lt_dtrace_work(int force) 515*10673SKrishnendu.Sadhukhan@Sun.COM { 516*10673SKrishnendu.Sadhukhan@Sun.COM static uint64_t last_snap = 0; 517*10673SKrishnendu.Sadhukhan@Sun.COM uint64_t now = lt_millisecond(); 518*10673SKrishnendu.Sadhukhan@Sun.COM 519*10673SKrishnendu.Sadhukhan@Sun.COM if (!force && now - last_snap < g_config.lt_cfg_snap_interval) { 520*10673SKrishnendu.Sadhukhan@Sun.COM return (last_snap + g_config.lt_cfg_snap_interval - now); 521*10673SKrishnendu.Sadhukhan@Sun.COM } 522*10673SKrishnendu.Sadhukhan@Sun.COM 523*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_status(g_dtp) == -1) { 524*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Failed when getting status: %s\n", 525*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); 526*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 527*10673SKrishnendu.Sadhukhan@Sun.COM } 528*10673SKrishnendu.Sadhukhan@Sun.COM 529*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_aggregate_snap(g_dtp) != 0) { 530*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Failed to snap aggregate: %s\n", 531*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); 532*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 533*10673SKrishnendu.Sadhukhan@Sun.COM } 534*10673SKrishnendu.Sadhukhan@Sun.COM 535*10673SKrishnendu.Sadhukhan@Sun.COM last_snap = now; 536*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 537*10673SKrishnendu.Sadhukhan@Sun.COM } 538*10673SKrishnendu.Sadhukhan@Sun.COM 539*10673SKrishnendu.Sadhukhan@Sun.COM /* 540*10673SKrishnendu.Sadhukhan@Sun.COM * Walk through dtrace aggregator and collect data for latencytop to display. 541*10673SKrishnendu.Sadhukhan@Sun.COM * Called immediately before UI update. 542*10673SKrishnendu.Sadhukhan@Sun.COM */ 543*10673SKrishnendu.Sadhukhan@Sun.COM int 544*10673SKrishnendu.Sadhukhan@Sun.COM lt_dtrace_collect(void) 545*10673SKrishnendu.Sadhukhan@Sun.COM { 546*10673SKrishnendu.Sadhukhan@Sun.COM if (lt_dtrace_work(1) != 0) { 547*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 548*10673SKrishnendu.Sadhukhan@Sun.COM } 549*10673SKrishnendu.Sadhukhan@Sun.COM 550*10673SKrishnendu.Sadhukhan@Sun.COM if (dtrace_aggregate_walk(g_dtp, aggwalk, NULL) != 0) { 551*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error("Failed to sort aggregate: %s\n", 552*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); 553*10673SKrishnendu.Sadhukhan@Sun.COM return (-1); 554*10673SKrishnendu.Sadhukhan@Sun.COM } 555*10673SKrishnendu.Sadhukhan@Sun.COM 556*10673SKrishnendu.Sadhukhan@Sun.COM /* 557*10673SKrishnendu.Sadhukhan@Sun.COM * Probably we don't need to clear again, because we have removed 558*10673SKrishnendu.Sadhukhan@Sun.COM * everything. Paranoid ? 559*10673SKrishnendu.Sadhukhan@Sun.COM */ 560*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_aggregate_clear(g_dtp); 561*10673SKrishnendu.Sadhukhan@Sun.COM 562*10673SKrishnendu.Sadhukhan@Sun.COM return (0); 563*10673SKrishnendu.Sadhukhan@Sun.COM } 564*10673SKrishnendu.Sadhukhan@Sun.COM 565*10673SKrishnendu.Sadhukhan@Sun.COM /* 566*10673SKrishnendu.Sadhukhan@Sun.COM * dtrace clean up. 567*10673SKrishnendu.Sadhukhan@Sun.COM */ 568*10673SKrishnendu.Sadhukhan@Sun.COM void 569*10673SKrishnendu.Sadhukhan@Sun.COM lt_dtrace_deinit(void) 570*10673SKrishnendu.Sadhukhan@Sun.COM { 571*10673SKrishnendu.Sadhukhan@Sun.COM (void) dtrace_stop(g_dtp); 572*10673SKrishnendu.Sadhukhan@Sun.COM dtrace_close(g_dtp); 573*10673SKrishnendu.Sadhukhan@Sun.COM } 574