1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/mutex.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/atomic.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/ftrace.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /* 43*7c478bd9Sstevel@tonic-gate * Tunable parameters: 44*7c478bd9Sstevel@tonic-gate * 45*7c478bd9Sstevel@tonic-gate * ftrace_atboot - whether to start fast tracing at boot. 46*7c478bd9Sstevel@tonic-gate * ftrace_nent - size of the per-CPU event ring buffer. 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate int ftrace_atboot = 0; 49*7c478bd9Sstevel@tonic-gate int ftrace_nent = FTRACE_NENT; 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate /* 52*7c478bd9Sstevel@tonic-gate * The current overall state of the ftrace subsystem. 53*7c478bd9Sstevel@tonic-gate * If FTRACE_READY is set, then tracing can be enabled. 54*7c478bd9Sstevel@tonic-gate * If FTRACE_ENABLED is set, tracing is enabled on the set of CPUs 55*7c478bd9Sstevel@tonic-gate * which are currently FTRACE_READY. 56*7c478bd9Sstevel@tonic-gate */ 57*7c478bd9Sstevel@tonic-gate static int ftrace_state = 0; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * Protects assignments to: 61*7c478bd9Sstevel@tonic-gate * ftrace_state 62*7c478bd9Sstevel@tonic-gate * cpu[N]->cpu_ftrace.ftd_state 63*7c478bd9Sstevel@tonic-gate * cpu[N]->cpu_ftrace.ftd_cur 64*7c478bd9Sstevel@tonic-gate * cpu[N]->cpu_ftrace.ftd_first 65*7c478bd9Sstevel@tonic-gate * cpu[N]->cpu_ftrace.ftd_last 66*7c478bd9Sstevel@tonic-gate * Does _not_ protect readers of cpu[N]->cpu_ftrace.ftd_state. 67*7c478bd9Sstevel@tonic-gate * Does not protect reading the FTRACE_READY bit in ftrace_state, 68*7c478bd9Sstevel@tonic-gate * since non-READY to READY is a stable transition. This is used 69*7c478bd9Sstevel@tonic-gate * to ensure ftrace_init() has been called. 70*7c478bd9Sstevel@tonic-gate */ 71*7c478bd9Sstevel@tonic-gate static kmutex_t ftrace_lock; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * Check whether a CPU is installed. 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate #define IS_CPU(i) (cpu[i] != NULL) 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate static void 79*7c478bd9Sstevel@tonic-gate ftrace_cpu_init(int cpuid) 80*7c478bd9Sstevel@tonic-gate { 81*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd; 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* 84*7c478bd9Sstevel@tonic-gate * This can be called with "cpu[cpuid]->cpu_flags & CPU_EXISTS" 85*7c478bd9Sstevel@tonic-gate * being false - e.g. when a CPU is DR'ed in. 86*7c478bd9Sstevel@tonic-gate */ 87*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ftrace_lock)); 88*7c478bd9Sstevel@tonic-gate ASSERT(IS_CPU(cpuid)); 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate ftd = &cpu[cpuid]->cpu_ftrace; 91*7c478bd9Sstevel@tonic-gate if (ftd->ftd_state & FTRACE_READY) 92*7c478bd9Sstevel@tonic-gate return; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate /* 95*7c478bd9Sstevel@tonic-gate * We don't allocate the buffers until the first time 96*7c478bd9Sstevel@tonic-gate * ftrace_cpu_start() is called, so that they're not 97*7c478bd9Sstevel@tonic-gate * allocated if ftrace is never enabled. 98*7c478bd9Sstevel@tonic-gate */ 99*7c478bd9Sstevel@tonic-gate ftd->ftd_state |= FTRACE_READY; 100*7c478bd9Sstevel@tonic-gate ASSERT(!(ftd->ftd_state & FTRACE_ENABLED)); 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * Only called from cpu_unconfigure() (and cpu_configure() on error). 105*7c478bd9Sstevel@tonic-gate * At this point, cpu[cpuid] is about to be freed and NULLed out, 106*7c478bd9Sstevel@tonic-gate * so we'd better clean up after ourselves. 107*7c478bd9Sstevel@tonic-gate */ 108*7c478bd9Sstevel@tonic-gate static void 109*7c478bd9Sstevel@tonic-gate ftrace_cpu_fini(int cpuid) 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ftrace_lock)); 114*7c478bd9Sstevel@tonic-gate ASSERT(IS_CPU(cpuid)); 115*7c478bd9Sstevel@tonic-gate ASSERT((cpu[cpuid]->cpu_flags & CPU_POWEROFF) != 0); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate ftd = &cpu[cpuid]->cpu_ftrace; 118*7c478bd9Sstevel@tonic-gate if (!(ftd->ftd_state & FTRACE_READY)) 119*7c478bd9Sstevel@tonic-gate return; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate /* 122*7c478bd9Sstevel@tonic-gate * Do not free mutex and the the trace buffer once they are 123*7c478bd9Sstevel@tonic-gate * allocated. A thread, preempted from the now powered-off CPU 124*7c478bd9Sstevel@tonic-gate * may be holding the mutex and in the middle of adding a trace 125*7c478bd9Sstevel@tonic-gate * record. 126*7c478bd9Sstevel@tonic-gate */ 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate static void 130*7c478bd9Sstevel@tonic-gate ftrace_cpu_start(int cpuid) 131*7c478bd9Sstevel@tonic-gate { 132*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ftrace_lock)); 135*7c478bd9Sstevel@tonic-gate ASSERT(IS_CPU(cpuid)); 136*7c478bd9Sstevel@tonic-gate ASSERT(ftrace_state & FTRACE_ENABLED); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate ftd = &cpu[cpuid]->cpu_ftrace; 139*7c478bd9Sstevel@tonic-gate if (ftd->ftd_state & FTRACE_READY) { 140*7c478bd9Sstevel@tonic-gate if (ftd->ftd_first == NULL) { 141*7c478bd9Sstevel@tonic-gate ftrace_record_t *ptrs; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate mutex_init(&ftd->ftd_mutex, NULL, MUTEX_DEFAULT, NULL); 144*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 145*7c478bd9Sstevel@tonic-gate ptrs = kmem_zalloc(ftrace_nent * 146*7c478bd9Sstevel@tonic-gate sizeof (ftrace_record_t), KM_SLEEP); 147*7c478bd9Sstevel@tonic-gate mutex_enter(&ftrace_lock); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate ftd->ftd_first = ptrs; 150*7c478bd9Sstevel@tonic-gate ftd->ftd_last = ptrs + (ftrace_nent - 1); 151*7c478bd9Sstevel@tonic-gate ftd->ftd_cur = ptrs; 152*7c478bd9Sstevel@tonic-gate membar_producer(); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate ftd->ftd_state |= FTRACE_ENABLED; 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate static void 159*7c478bd9Sstevel@tonic-gate ftrace_cpu_stop(int cpuid) 160*7c478bd9Sstevel@tonic-gate { 161*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ftrace_lock)); 162*7c478bd9Sstevel@tonic-gate ASSERT(IS_CPU(cpuid)); 163*7c478bd9Sstevel@tonic-gate cpu[cpuid]->cpu_ftrace.ftd_state &= ~(FTRACE_ENABLED); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * Hook for DR. 168*7c478bd9Sstevel@tonic-gate */ 169*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 170*7c478bd9Sstevel@tonic-gate int 171*7c478bd9Sstevel@tonic-gate ftrace_cpu_setup(cpu_setup_t what, int id, void *arg) 172*7c478bd9Sstevel@tonic-gate { 173*7c478bd9Sstevel@tonic-gate if (!(ftrace_state & FTRACE_READY)) 174*7c478bd9Sstevel@tonic-gate return (0); 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate switch (what) { 177*7c478bd9Sstevel@tonic-gate case CPU_CONFIG: 178*7c478bd9Sstevel@tonic-gate mutex_enter(&ftrace_lock); 179*7c478bd9Sstevel@tonic-gate ftrace_cpu_init(id); 180*7c478bd9Sstevel@tonic-gate if (ftrace_state & FTRACE_ENABLED) 181*7c478bd9Sstevel@tonic-gate ftrace_cpu_start(id); 182*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 183*7c478bd9Sstevel@tonic-gate break; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate case CPU_UNCONFIG: 186*7c478bd9Sstevel@tonic-gate mutex_enter(&ftrace_lock); 187*7c478bd9Sstevel@tonic-gate ftrace_cpu_fini(id); 188*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 189*7c478bd9Sstevel@tonic-gate break; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate default: 192*7c478bd9Sstevel@tonic-gate break; 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate return (0); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate void 198*7c478bd9Sstevel@tonic-gate ftrace_init(void) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate int i; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate ASSERT(!(ftrace_state & FTRACE_READY)); 203*7c478bd9Sstevel@tonic-gate mutex_init(&ftrace_lock, NULL, MUTEX_DEFAULT, NULL); 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate mutex_enter(&ftrace_lock); 206*7c478bd9Sstevel@tonic-gate for (i = 0; i < NCPU; i++) { 207*7c478bd9Sstevel@tonic-gate if (IS_CPU(i)) { 208*7c478bd9Sstevel@tonic-gate /* should have been kmem_zalloc()'ed */ 209*7c478bd9Sstevel@tonic-gate ASSERT(cpu[i]->cpu_ftrace.ftd_state == 0); 210*7c478bd9Sstevel@tonic-gate ASSERT(cpu[i]->cpu_ftrace.ftd_first == NULL); 211*7c478bd9Sstevel@tonic-gate ASSERT(cpu[i]->cpu_ftrace.ftd_last == NULL); 212*7c478bd9Sstevel@tonic-gate ASSERT(cpu[i]->cpu_ftrace.ftd_cur == NULL); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate if (ftrace_nent < 1) { 217*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 218*7c478bd9Sstevel@tonic-gate return; 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate for (i = 0; i < NCPU; i++) 222*7c478bd9Sstevel@tonic-gate if (IS_CPU(i)) 223*7c478bd9Sstevel@tonic-gate ftrace_cpu_init(i); 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate ftrace_state |= FTRACE_READY; 226*7c478bd9Sstevel@tonic-gate mutex_enter(&cpu_lock); 227*7c478bd9Sstevel@tonic-gate register_cpu_setup_func(ftrace_cpu_setup, NULL); 228*7c478bd9Sstevel@tonic-gate mutex_exit(&cpu_lock); 229*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate if (ftrace_atboot) 232*7c478bd9Sstevel@tonic-gate (void) ftrace_start(); 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate int 236*7c478bd9Sstevel@tonic-gate ftrace_start(void) 237*7c478bd9Sstevel@tonic-gate { 238*7c478bd9Sstevel@tonic-gate int i, was_enabled = 0; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate if (ftrace_state & FTRACE_READY) { 241*7c478bd9Sstevel@tonic-gate mutex_enter(&ftrace_lock); 242*7c478bd9Sstevel@tonic-gate was_enabled = ((ftrace_state & FTRACE_ENABLED) != 0); 243*7c478bd9Sstevel@tonic-gate ftrace_state |= FTRACE_ENABLED; 244*7c478bd9Sstevel@tonic-gate for (i = 0; i < NCPU; i++) 245*7c478bd9Sstevel@tonic-gate if (IS_CPU(i)) 246*7c478bd9Sstevel@tonic-gate ftrace_cpu_start(i); 247*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate return (was_enabled); 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate int 254*7c478bd9Sstevel@tonic-gate ftrace_stop(void) 255*7c478bd9Sstevel@tonic-gate { 256*7c478bd9Sstevel@tonic-gate int i, was_enabled = 0; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate if (ftrace_state & FTRACE_READY) { 259*7c478bd9Sstevel@tonic-gate mutex_enter(&ftrace_lock); 260*7c478bd9Sstevel@tonic-gate if (ftrace_state & FTRACE_ENABLED) { 261*7c478bd9Sstevel@tonic-gate was_enabled = 1; 262*7c478bd9Sstevel@tonic-gate for (i = 0; i < NCPU; i++) 263*7c478bd9Sstevel@tonic-gate if (IS_CPU(i)) 264*7c478bd9Sstevel@tonic-gate ftrace_cpu_stop(i); 265*7c478bd9Sstevel@tonic-gate ftrace_state &= ~(FTRACE_ENABLED); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate mutex_exit(&ftrace_lock); 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate return (was_enabled); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate void 273*7c478bd9Sstevel@tonic-gate ftrace_0(char *str) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate ftrace_record_t *r; 276*7c478bd9Sstevel@tonic-gate struct cpu *cp = CPU; 277*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd = &cp->cpu_ftrace; 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate if (mutex_tryenter(&ftd->ftd_mutex) == 0) { 280*7c478bd9Sstevel@tonic-gate if (CPU_ON_INTR(cp)) 281*7c478bd9Sstevel@tonic-gate return; 282*7c478bd9Sstevel@tonic-gate else 283*7c478bd9Sstevel@tonic-gate mutex_enter(&ftd->ftd_mutex); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate r = ftd->ftd_cur; 286*7c478bd9Sstevel@tonic-gate r->ftr_event = str; 287*7c478bd9Sstevel@tonic-gate r->ftr_thread = curthread; 288*7c478bd9Sstevel@tonic-gate r->ftr_tick = gethrtime_unscaled(); 289*7c478bd9Sstevel@tonic-gate r->ftr_caller = caller(); 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate if (r++ == ftd->ftd_last) 292*7c478bd9Sstevel@tonic-gate r = ftd->ftd_first; 293*7c478bd9Sstevel@tonic-gate ftd->ftd_cur = r; 294*7c478bd9Sstevel@tonic-gate mutex_exit(&ftd->ftd_mutex); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate void 298*7c478bd9Sstevel@tonic-gate ftrace_1(char *str, ulong_t arg1) 299*7c478bd9Sstevel@tonic-gate { 300*7c478bd9Sstevel@tonic-gate ftrace_record_t *r; 301*7c478bd9Sstevel@tonic-gate struct cpu *cp = CPU; 302*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd = &cp->cpu_ftrace; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate if (mutex_tryenter(&ftd->ftd_mutex) == 0) { 305*7c478bd9Sstevel@tonic-gate if (CPU_ON_INTR(cp)) 306*7c478bd9Sstevel@tonic-gate return; 307*7c478bd9Sstevel@tonic-gate else 308*7c478bd9Sstevel@tonic-gate mutex_enter(&ftd->ftd_mutex); 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate r = ftd->ftd_cur; 311*7c478bd9Sstevel@tonic-gate r->ftr_event = str; 312*7c478bd9Sstevel@tonic-gate r->ftr_thread = curthread; 313*7c478bd9Sstevel@tonic-gate r->ftr_tick = gethrtime_unscaled(); 314*7c478bd9Sstevel@tonic-gate r->ftr_caller = caller(); 315*7c478bd9Sstevel@tonic-gate r->ftr_data1 = arg1; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate if (r++ == ftd->ftd_last) 318*7c478bd9Sstevel@tonic-gate r = ftd->ftd_first; 319*7c478bd9Sstevel@tonic-gate ftd->ftd_cur = r; 320*7c478bd9Sstevel@tonic-gate mutex_exit(&ftd->ftd_mutex); 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate void 324*7c478bd9Sstevel@tonic-gate ftrace_2(char *str, ulong_t arg1, ulong_t arg2) 325*7c478bd9Sstevel@tonic-gate { 326*7c478bd9Sstevel@tonic-gate ftrace_record_t *r; 327*7c478bd9Sstevel@tonic-gate struct cpu *cp = CPU; 328*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd = &cp->cpu_ftrace; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate if (mutex_tryenter(&ftd->ftd_mutex) == 0) { 331*7c478bd9Sstevel@tonic-gate if (CPU_ON_INTR(cp)) 332*7c478bd9Sstevel@tonic-gate return; 333*7c478bd9Sstevel@tonic-gate else 334*7c478bd9Sstevel@tonic-gate mutex_enter(&ftd->ftd_mutex); 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate r = ftd->ftd_cur; 337*7c478bd9Sstevel@tonic-gate r->ftr_event = str; 338*7c478bd9Sstevel@tonic-gate r->ftr_thread = curthread; 339*7c478bd9Sstevel@tonic-gate r->ftr_tick = gethrtime_unscaled(); 340*7c478bd9Sstevel@tonic-gate r->ftr_caller = caller(); 341*7c478bd9Sstevel@tonic-gate r->ftr_data1 = arg1; 342*7c478bd9Sstevel@tonic-gate r->ftr_data2 = arg2; 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate if (r++ == ftd->ftd_last) 345*7c478bd9Sstevel@tonic-gate r = ftd->ftd_first; 346*7c478bd9Sstevel@tonic-gate ftd->ftd_cur = r; 347*7c478bd9Sstevel@tonic-gate mutex_exit(&ftd->ftd_mutex); 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate void 351*7c478bd9Sstevel@tonic-gate ftrace_3(char *str, ulong_t arg1, ulong_t arg2, ulong_t arg3) 352*7c478bd9Sstevel@tonic-gate { 353*7c478bd9Sstevel@tonic-gate ftrace_record_t *r; 354*7c478bd9Sstevel@tonic-gate struct cpu *cp = CPU; 355*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd = &cp->cpu_ftrace; 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if (mutex_tryenter(&ftd->ftd_mutex) == 0) { 358*7c478bd9Sstevel@tonic-gate if (CPU_ON_INTR(cp)) 359*7c478bd9Sstevel@tonic-gate return; 360*7c478bd9Sstevel@tonic-gate else 361*7c478bd9Sstevel@tonic-gate mutex_enter(&ftd->ftd_mutex); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate r = ftd->ftd_cur; 364*7c478bd9Sstevel@tonic-gate r->ftr_event = str; 365*7c478bd9Sstevel@tonic-gate r->ftr_thread = curthread; 366*7c478bd9Sstevel@tonic-gate r->ftr_tick = gethrtime_unscaled(); 367*7c478bd9Sstevel@tonic-gate r->ftr_caller = caller(); 368*7c478bd9Sstevel@tonic-gate r->ftr_data1 = arg1; 369*7c478bd9Sstevel@tonic-gate r->ftr_data2 = arg2; 370*7c478bd9Sstevel@tonic-gate r->ftr_data3 = arg3; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate if (r++ == ftd->ftd_last) 373*7c478bd9Sstevel@tonic-gate r = ftd->ftd_first; 374*7c478bd9Sstevel@tonic-gate ftd->ftd_cur = r; 375*7c478bd9Sstevel@tonic-gate mutex_exit(&ftd->ftd_mutex); 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate void 379*7c478bd9Sstevel@tonic-gate ftrace_3_notick(char *str, ulong_t arg1, ulong_t arg2, ulong_t arg3) 380*7c478bd9Sstevel@tonic-gate { 381*7c478bd9Sstevel@tonic-gate ftrace_record_t *r; 382*7c478bd9Sstevel@tonic-gate struct cpu *cp = CPU; 383*7c478bd9Sstevel@tonic-gate ftrace_data_t *ftd = &cp->cpu_ftrace; 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate if (mutex_tryenter(&ftd->ftd_mutex) == 0) { 386*7c478bd9Sstevel@tonic-gate if (CPU_ON_INTR(cp)) 387*7c478bd9Sstevel@tonic-gate return; 388*7c478bd9Sstevel@tonic-gate else 389*7c478bd9Sstevel@tonic-gate mutex_enter(&ftd->ftd_mutex); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate r = ftd->ftd_cur; 392*7c478bd9Sstevel@tonic-gate r->ftr_event = str; 393*7c478bd9Sstevel@tonic-gate r->ftr_thread = curthread; 394*7c478bd9Sstevel@tonic-gate r->ftr_tick = 0; 395*7c478bd9Sstevel@tonic-gate r->ftr_caller = caller(); 396*7c478bd9Sstevel@tonic-gate r->ftr_data1 = arg1; 397*7c478bd9Sstevel@tonic-gate r->ftr_data2 = arg2; 398*7c478bd9Sstevel@tonic-gate r->ftr_data3 = arg3; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate if (r++ == ftd->ftd_last) 401*7c478bd9Sstevel@tonic-gate r = ftd->ftd_first; 402*7c478bd9Sstevel@tonic-gate ftd->ftd_cur = r; 403*7c478bd9Sstevel@tonic-gate mutex_exit(&ftd->ftd_mutex); 404*7c478bd9Sstevel@tonic-gate } 405