1119936Sjhb/*- 2119936Sjhb * Copyright (c) 2000 John Baldwin <jhb@FreeBSD.org> 3119936Sjhb * All rights reserved. 465556Sjasone * 565556Sjasone * Redistribution and use in source and binary forms, with or without 665556Sjasone * modification, are permitted provided that the following conditions 765556Sjasone * are met: 865556Sjasone * 1. Redistributions of source code must retain the above copyright 965556Sjasone * notice, this list of conditions and the following disclaimer. 1065556Sjasone * 2. Redistributions in binary form must reproduce the above copyright 1165556Sjasone * notice, this list of conditions and the following disclaimer in the 1265556Sjasone * documentation and/or other materials provided with the distribution. 1365556Sjasone * 14119936Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1565556Sjasone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1665556Sjasone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17119936Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18119936Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19119936Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20119936Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21119936Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22119936Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23119936Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24119936Sjhb * SUCH DAMAGE. 2565556Sjasone */ 2665556Sjasone 2765556Sjasone/* 2868420Sjhb * This module holds the global variables used by KTR and the ktr_tracepoint() 2968420Sjhb * function that does the actual tracing. 3065556Sjasone */ 3165556Sjasone 32116182Sobrien#include <sys/cdefs.h> 33116182Sobrien__FBSDID("$FreeBSD$"); 34116182Sobrien 3570035Sjhb#include "opt_ddb.h" 3668420Sjhb#include "opt_ktr.h" 37103787Sjeff#include "opt_alq.h" 3868420Sjhb 3970035Sjhb#include <sys/param.h> 40222813Sattilio#include <sys/queue.h> 41103787Sjeff#include <sys/alq.h> 4270035Sjhb#include <sys/cons.h> 43222813Sattilio#include <sys/cpuset.h> 4470705Sjhb#include <sys/kernel.h> 4565556Sjasone#include <sys/ktr.h> 4668420Sjhb#include <sys/libkern.h> 47243046Sjeff#include <sys/lock.h> 48243046Sjeff#include <sys/malloc.h> 49243046Sjeff#include <sys/mutex.h> 5087793Sjhb#include <sys/proc.h> 51243046Sjeff#include <sys/smp.h> 5265556Sjasone#include <sys/sysctl.h> 5368420Sjhb#include <sys/systm.h> 5478784Sjhb#include <sys/time.h> 5565556Sjasone 5693503Sjake#include <machine/cpu.h> 5793950Sjake#ifdef __sparc64__ 5893950Sjake#include <machine/ktr.h> 5993950Sjake#endif 6093503Sjake 61160312Sjhb#ifdef DDB 6270035Sjhb#include <ddb/ddb.h> 63160312Sjhb#include <ddb/db_output.h> 64160312Sjhb#endif 6570035Sjhb 66246282Savg#ifndef KTR_BOOT_ENTRIES 67246282Savg#define KTR_BOOT_ENTRIES 1024 68246282Savg#endif 69246282Savg 7078784Sjhb#ifndef KTR_ENTRIES 7178784Sjhb#define KTR_ENTRIES 1024 7278784Sjhb#endif 7378784Sjhb 74243046Sjeff/* Limit the allocations to something manageable. */ 75243046Sjeff#define KTR_ENTRIES_MAX (8 * 1024 * 1024) 76243046Sjeff 7768420Sjhb#ifndef KTR_MASK 78210337Sattilio#define KTR_MASK (0) 7968420Sjhb#endif 8068420Sjhb 81239923Sattilio#ifndef KTR_CPUMASK 82239923Sattilio#define KTR_CPUMASK CPUSET_FSET 83239923Sattilio#endif 84239923Sattilio 8593503Sjake#ifndef KTR_TIME 8693503Sjake#define KTR_TIME get_cyclecount() 8768420Sjhb#endif 8868420Sjhb 8993503Sjake#ifndef KTR_CPU 9093503Sjake#define KTR_CPU PCPU_GET(cpuid) 9170705Sjhb#endif 9270705Sjhb 93243046Sjeffstatic MALLOC_DEFINE(M_KTR, "KTR", "KTR"); 94243046Sjeff 95219028SnetchildFEATURE(ktr, "Kernel support for KTR kernel tracing facility"); 96219028Snetchild 97243046Sjeffvolatile int ktr_idx = 0; 98243046Sjeffint ktr_mask = KTR_MASK; 99243046Sjeffint ktr_compile = KTR_COMPILE; 100246282Savgint ktr_entries = KTR_BOOT_ENTRIES; 101243046Sjeffint ktr_version = KTR_VERSION; 102246282Savgstruct ktr_entry ktr_buf_init[KTR_BOOT_ENTRIES]; 103243046Sjeffstruct ktr_entry *ktr_buf = ktr_buf_init; 104243046Sjeffcpuset_t ktr_cpumask = CPUSET_T_INITIALIZER(KTR_CPUMASK); 105243046Sjeffstatic char ktr_cpumask_str[CPUSETBUFSIZ]; 10670705Sjhb 10777900SpeterTUNABLE_INT("debug.ktr.mask", &ktr_mask); 10865556Sjasone 109243046SjeffTUNABLE_STR("debug.ktr.cpumask", ktr_cpumask_str, sizeof(ktr_cpumask_str)); 110132583Srwatson 111243046Sjeffstatic SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options"); 11265556Sjasone 113205017SjhbSYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, 114205017Sjhb &ktr_version, 0, "Version of the KTR interface"); 11593503Sjake 116243971SalfredSYSCTL_UINT(_debug_ktr, OID_AUTO, compile, CTLFLAG_RD, 117243046Sjeff &ktr_compile, 0, "Bitmask of KTR event classes compiled into the kernel"); 118222813Sattilio 119222813Sattiliostatic void 120222813Sattilioktr_cpumask_initializer(void *dummy __unused) 121222813Sattilio{ 122222813Sattilio 123222813Sattilio /* 124222813Sattilio * TUNABLE_STR() runs with SI_ORDER_MIDDLE priority, thus it must be 125222813Sattilio * already set, if necessary. 126222813Sattilio */ 127222813Sattilio if (ktr_cpumask_str[0] != '\0' && 128222813Sattilio cpusetobj_strscan(&ktr_cpumask, ktr_cpumask_str) == -1) 129222813Sattilio CPU_FILL(&ktr_cpumask); 130222813Sattilio} 131222813SattilioSYSINIT(ktr_cpumask_initializer, SI_SUB_TUNABLES, SI_ORDER_ANY, 132222813Sattilio ktr_cpumask_initializer, NULL); 133222813Sattilio 134222813Sattiliostatic int 135222813Sattiliosysctl_debug_ktr_cpumask(SYSCTL_HANDLER_ARGS) 136222813Sattilio{ 137222813Sattilio char lktr_cpumask_str[CPUSETBUFSIZ]; 138222813Sattilio cpuset_t imask; 139222813Sattilio int error; 140222813Sattilio 141222813Sattilio cpusetobj_strprint(lktr_cpumask_str, &ktr_cpumask); 142222813Sattilio error = sysctl_handle_string(oidp, lktr_cpumask_str, 143222813Sattilio sizeof(lktr_cpumask_str), req); 144222813Sattilio if (error != 0 || req->newptr == NULL) 145222813Sattilio return (error); 146222813Sattilio if (cpusetobj_strscan(&imask, lktr_cpumask_str) == -1) 147222813Sattilio return (EINVAL); 148222813Sattilio CPU_COPY(&imask, &ktr_cpumask); 149222813Sattilio 150222813Sattilio return (error); 151222813Sattilio} 152222813SattilioSYSCTL_PROC(_debug_ktr, OID_AUTO, cpumask, 153222813Sattilio CTLFLAG_RW | CTLFLAG_MPSAFE | CTLTYPE_STRING, NULL, 0, 154222813Sattilio sysctl_debug_ktr_cpumask, "S", 155222813Sattilio "Bitmask of CPUs on which KTR logging is enabled"); 156222813Sattilio 157154933Sjhbstatic int 158154933Sjhbsysctl_debug_ktr_clear(SYSCTL_HANDLER_ARGS) 159154933Sjhb{ 160154933Sjhb int clear, error; 161154933Sjhb 162154933Sjhb clear = 0; 163154933Sjhb error = sysctl_handle_int(oidp, &clear, 0, req); 164154933Sjhb if (error || !req->newptr) 165154933Sjhb return (error); 166154933Sjhb 167154933Sjhb if (clear) { 168243046Sjeff bzero(ktr_buf, sizeof(*ktr_buf) * ktr_entries); 169154933Sjhb ktr_idx = 0; 170154933Sjhb } 171154933Sjhb 172154933Sjhb return (error); 173154933Sjhb} 174154933SjhbSYSCTL_PROC(_debug_ktr, OID_AUTO, clear, CTLTYPE_INT|CTLFLAG_RW, 0, 0, 175154933Sjhb sysctl_debug_ktr_clear, "I", "Clear KTR Buffer"); 176154933Sjhb 177243046Sjeff/* 178243046Sjeff * This is a sysctl proc so that it is serialized as !MPSAFE along with 179243046Sjeff * the other ktr sysctl procs. 180243046Sjeff */ 181243046Sjeffstatic int 182243046Sjeffsysctl_debug_ktr_mask(SYSCTL_HANDLER_ARGS) 183243046Sjeff{ 184243046Sjeff int mask, error; 185243046Sjeff 186243046Sjeff mask = ktr_mask; 187243046Sjeff error = sysctl_handle_int(oidp, &mask, 0, req); 188243046Sjeff if (error || !req->newptr) 189243046Sjeff return (error); 190243046Sjeff ktr_mask = mask; 191243046Sjeff return (error); 192243046Sjeff} 193243046Sjeff 194243971SalfredSYSCTL_PROC(_debug_ktr, OID_AUTO, mask, CTLTYPE_UINT|CTLFLAG_RW, 0, 0, 195243971Salfred sysctl_debug_ktr_mask, "IU", 196243046Sjeff "Bitmask of KTR event classes for which logging is enabled"); 197243046Sjeff 198246331Savg#if KTR_ENTRIES > KTR_BOOT_ENTRIES 199246282Savg/* 200246282Savg * A simplified version of sysctl_debug_ktr_entries. 201246282Savg * No need to care about SMP, scheduling, etc. 202246282Savg */ 203246282Savgstatic void 204246282Savgktr_entries_initializer(void *dummy __unused) 205246282Savg{ 206246282Savg int mask; 207246282Savg 208246282Savg /* Temporarily disable ktr in case malloc() is being traced. */ 209246282Savg mask = ktr_mask; 210246282Savg ktr_mask = 0; 211246282Savg ktr_buf = malloc(sizeof(*ktr_buf) * KTR_ENTRIES, M_KTR, 212246282Savg M_WAITOK | M_ZERO); 213246530Savg memcpy(ktr_buf, ktr_buf_init + ktr_idx, 214246530Savg (KTR_BOOT_ENTRIES - ktr_idx) * sizeof(*ktr_buf)); 215246530Savg if (ktr_idx != 0) 216246530Savg memcpy(ktr_buf + KTR_BOOT_ENTRIES - ktr_idx, ktr_buf_init, 217246530Savg ktr_idx * sizeof(*ktr_buf)); 218246282Savg ktr_entries = KTR_ENTRIES; 219246282Savg ktr_mask = mask; 220246282Savg} 221246282SavgSYSINIT(ktr_entries_initializer, SI_SUB_KMEM, SI_ORDER_ANY, 222246282Savg ktr_entries_initializer, NULL); 223246282Savg#endif 224246282Savg 225243046Sjeffstatic int 226243046Sjeffsysctl_debug_ktr_entries(SYSCTL_HANDLER_ARGS) 227243046Sjeff{ 228243046Sjeff int entries, error, mask; 229243046Sjeff struct ktr_entry *buf, *oldbuf; 230243046Sjeff 231243046Sjeff entries = ktr_entries; 232243046Sjeff error = sysctl_handle_int(oidp, &entries, 0, req); 233243046Sjeff if (error || !req->newptr) 234243046Sjeff return (error); 235243046Sjeff if (entries > KTR_ENTRIES_MAX) 236243046Sjeff return (ERANGE); 237243046Sjeff /* Disable ktr temporarily. */ 238243046Sjeff mask = ktr_mask; 239243046Sjeff atomic_store_rel_int(&ktr_mask, 0); 240243046Sjeff /* Wait for threads to go idle. */ 241243046Sjeff if ((error = quiesce_all_cpus("ktrent", PCATCH)) != 0) { 242243046Sjeff ktr_mask = mask; 243243046Sjeff return (error); 244243046Sjeff } 245243046Sjeff if (ktr_buf != ktr_buf_init) 246243046Sjeff oldbuf = ktr_buf; 247243046Sjeff else 248243046Sjeff oldbuf = NULL; 249243046Sjeff /* Allocate a new buffer. */ 250243046Sjeff buf = malloc(sizeof(*buf) * entries, M_KTR, M_WAITOK | M_ZERO); 251243046Sjeff /* Install the new buffer and restart ktr. */ 252243046Sjeff ktr_buf = buf; 253243046Sjeff ktr_entries = entries; 254243046Sjeff ktr_idx = 0; 255243046Sjeff atomic_store_rel_int(&ktr_mask, mask); 256243046Sjeff if (oldbuf != NULL) 257243046Sjeff free(oldbuf, M_KTR); 258243046Sjeff 259243046Sjeff return (error); 260243046Sjeff} 261243046Sjeff 262243046SjeffSYSCTL_PROC(_debug_ktr, OID_AUTO, entries, CTLTYPE_INT|CTLFLAG_RW, 0, 0, 263243046Sjeff sysctl_debug_ktr_entries, "I", "Number of entries in the KTR buffer"); 264243046Sjeff 26593503Sjake#ifdef KTR_VERBOSE 26693503Sjakeint ktr_verbose = KTR_VERBOSE; 26777900SpeterTUNABLE_INT("debug.ktr.verbose", &ktr_verbose); 26870705SjhbSYSCTL_INT(_debug_ktr, OID_AUTO, verbose, CTLFLAG_RW, &ktr_verbose, 0, ""); 26993503Sjake#endif 27068420Sjhb 271103787Sjeff#ifdef KTR_ALQ 272103787Sjeffstruct alq *ktr_alq; 273103787Sjeffchar ktr_alq_file[MAXPATHLEN] = "/tmp/ktr.out"; 274103787Sjeffint ktr_alq_cnt = 0; 275103787Sjeffint ktr_alq_depth = KTR_ENTRIES; 276103787Sjeffint ktr_alq_enabled = 0; 277103787Sjeffint ktr_alq_failed = 0; 278103787Sjeffint ktr_alq_max = 0; 279103787Sjeff 280103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_max, CTLFLAG_RW, &ktr_alq_max, 0, 281103787Sjeff "Maximum number of entries to write"); 282103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_cnt, CTLFLAG_RD, &ktr_alq_cnt, 0, 283103787Sjeff "Current number of written entries"); 284103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_failed, CTLFLAG_RD, &ktr_alq_failed, 0, 285103787Sjeff "Number of times we overran the buffer"); 286103787SjeffSYSCTL_INT(_debug_ktr, OID_AUTO, alq_depth, CTLFLAG_RW, &ktr_alq_depth, 0, 287103787Sjeff "Number of items in the write buffer"); 288103787SjeffSYSCTL_STRING(_debug_ktr, OID_AUTO, alq_file, CTLFLAG_RW, ktr_alq_file, 289103787Sjeff sizeof(ktr_alq_file), "KTR logging file"); 290103787Sjeff 291103787Sjeffstatic int 292103787Sjeffsysctl_debug_ktr_alq_enable(SYSCTL_HANDLER_ARGS) 293103787Sjeff{ 294103787Sjeff int error; 295103787Sjeff int enable; 296103787Sjeff 297103787Sjeff enable = ktr_alq_enabled; 298103787Sjeff 299154940Sjhb error = sysctl_handle_int(oidp, &enable, 0, req); 300154940Sjhb if (error || !req->newptr) 301154940Sjhb return (error); 302103787Sjeff 303103787Sjeff if (enable) { 304103787Sjeff if (ktr_alq_enabled) 305103787Sjeff return (0); 306116697Srwatson error = alq_open(&ktr_alq, (const char *)ktr_alq_file, 307145142Srwatson req->td->td_ucred, ALQ_DEFAULT_CMODE, 308145142Srwatson sizeof(struct ktr_entry), ktr_alq_depth); 309103787Sjeff if (error == 0) { 310103787Sjeff ktr_alq_cnt = 0; 311103787Sjeff ktr_alq_failed = 0; 312103787Sjeff ktr_alq_enabled = 1; 313103787Sjeff } 314103787Sjeff } else { 315103787Sjeff if (ktr_alq_enabled == 0) 316103787Sjeff return (0); 317103787Sjeff ktr_alq_enabled = 0; 318103787Sjeff alq_close(ktr_alq); 319103787Sjeff ktr_alq = NULL; 320103787Sjeff } 321103787Sjeff 322103787Sjeff return (error); 323103787Sjeff} 324103787SjeffSYSCTL_PROC(_debug_ktr, OID_AUTO, alq_enable, 325103787Sjeff CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_debug_ktr_alq_enable, 326103787Sjeff "I", "Enable KTR logging"); 327103787Sjeff#endif 328103787Sjeff 32968420Sjhbvoid 33093503Sjakektr_tracepoint(u_int mask, const char *file, int line, const char *format, 33193503Sjake u_long arg1, u_long arg2, u_long arg3, u_long arg4, u_long arg5, 33293503Sjake u_long arg6) 33368420Sjhb{ 33468420Sjhb struct ktr_entry *entry; 335103787Sjeff#ifdef KTR_ALQ 336103787Sjeff struct ale *ale = NULL; 337206632Sjulian#endif 33874903Sjhb int newindex, saveindex; 339103787Sjeff#if defined(KTR_VERBOSE) || defined(KTR_ALQ) 34087793Sjhb struct thread *td; 34193503Sjake#endif 34291904Sjhb int cpu; 34368420Sjhb 34469880Sjhb if (panicstr) 34569880Sjhb return; 346243046Sjeff if ((ktr_mask & mask) == 0 || ktr_buf == NULL) 34768420Sjhb return; 34893503Sjake cpu = KTR_CPU; 349222813Sattilio if (!CPU_ISSET(cpu, &ktr_cpumask)) 35093503Sjake return; 351103787Sjeff#if defined(KTR_VERBOSE) || defined(KTR_ALQ) 35287793Sjhb td = curthread; 353116101Sjhb if (td->td_pflags & TDP_INKTR) 35487793Sjhb return; 355116101Sjhb td->td_pflags |= TDP_INKTR; 35693503Sjake#endif 357103787Sjeff#ifdef KTR_ALQ 358206632Sjulian if (ktr_alq_enabled) { 359206632Sjulian if (td->td_critnest == 0 && 360206632Sjulian (td->td_flags & TDF_IDLETD) == 0 && 361206632Sjulian td != ald_thread) { 362206632Sjulian if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max) 363206632Sjulian goto done; 364206632Sjulian if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) { 365206632Sjulian ktr_alq_failed++; 366206632Sjulian goto done; 367206632Sjulian } 368206632Sjulian ktr_alq_cnt++; 369206632Sjulian entry = (struct ktr_entry *)ale->ae_data; 370206632Sjulian } else { 371103787Sjeff goto done; 372103787Sjeff } 373103787Sjeff } else 374103787Sjeff#endif 375206632Sjulian { 376206632Sjulian do { 377206632Sjulian saveindex = ktr_idx; 378243046Sjeff newindex = (saveindex + 1) % ktr_entries; 379206632Sjulian } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0); 380206632Sjulian entry = &ktr_buf[saveindex]; 381206632Sjulian } 38293503Sjake entry->ktr_timestamp = KTR_TIME; 38391904Sjhb entry->ktr_cpu = cpu; 384147278Sjeff entry->ktr_thread = curthread; 385112105Sjhb if (file != NULL) 386112105Sjhb while (strncmp(file, "../", 3) == 0) 387112105Sjhb file += 3; 38893503Sjake entry->ktr_file = file; 38968420Sjhb entry->ktr_line = line; 39093503Sjake#ifdef KTR_VERBOSE 39168420Sjhb if (ktr_verbose) { 39268782Sjhb#ifdef SMP 39393503Sjake printf("cpu%d ", cpu); 39468782Sjhb#endif 39593503Sjake if (ktr_verbose > 1) { 39693503Sjake printf("%s.%d\t", entry->ktr_file, 39793503Sjake entry->ktr_line); 39893503Sjake } 39993503Sjake printf(format, arg1, arg2, arg3, arg4, arg5, arg6); 40068420Sjhb printf("\n"); 40168420Sjhb } 40293503Sjake#endif 40368420Sjhb entry->ktr_desc = format; 40493503Sjake entry->ktr_parms[0] = arg1; 40593503Sjake entry->ktr_parms[1] = arg2; 40693503Sjake entry->ktr_parms[2] = arg3; 40793503Sjake entry->ktr_parms[3] = arg4; 40893503Sjake entry->ktr_parms[4] = arg5; 40993503Sjake entry->ktr_parms[5] = arg6; 410103787Sjeff#ifdef KTR_ALQ 411206632Sjulian if (ktr_alq_enabled && ale) 412103787Sjeff alq_post(ktr_alq, ale); 413103787Sjeffdone: 414103787Sjeff#endif 415103787Sjeff#if defined(KTR_VERBOSE) || defined(KTR_ALQ) 416116101Sjhb td->td_pflags &= ~TDP_INKTR; 41768420Sjhb#endif 41868420Sjhb} 41970035Sjhb 42070035Sjhb#ifdef DDB 42170035Sjhb 42270035Sjhbstruct tstate { 42370035Sjhb int cur; 42470035Sjhb int first; 42570035Sjhb}; 42670035Sjhbstatic struct tstate tstate; 42770035Sjhbstatic int db_ktr_verbose; 42870035Sjhbstatic int db_mach_vtrace(void); 42970035Sjhb 43072755SjhbDB_SHOW_COMMAND(ktr, db_ktr_all) 43170035Sjhb{ 432118269Sjhb 433243046Sjeff tstate.cur = (ktr_idx - 1) % ktr_entries; 43470035Sjhb tstate.first = -1; 435206632Sjulian db_ktr_verbose = 0; 436229272Sed db_ktr_verbose |= (strchr(modif, 'v') != NULL) ? 2 : 0; 437229272Sed db_ktr_verbose |= (strchr(modif, 'V') != NULL) ? 1 : 0; /* just timestap please */ 438229272Sed if (strchr(modif, 'a') != NULL) { 439160312Sjhb db_disable_pager(); 440118269Sjhb while (cncheckc() != -1) 441118269Sjhb if (db_mach_vtrace() == 0) 44272755Sjhb break; 443118269Sjhb } else { 444160312Sjhb while (!db_pager_quit) 445118269Sjhb if (db_mach_vtrace() == 0) 44672755Sjhb break; 447118269Sjhb } 44870035Sjhb} 44970035Sjhb 45070035Sjhbstatic int 45170035Sjhbdb_mach_vtrace(void) 45270035Sjhb{ 45370035Sjhb struct ktr_entry *kp; 45470035Sjhb 455243046Sjeff if (tstate.cur == tstate.first || ktr_buf == NULL) { 45670035Sjhb db_printf("--- End of trace buffer ---\n"); 45770035Sjhb return (0); 45870035Sjhb } 45970035Sjhb kp = &ktr_buf[tstate.cur]; 46070035Sjhb 46170035Sjhb /* Skip over unused entries. */ 46272755Sjhb if (kp->ktr_desc == NULL) { 46372755Sjhb db_printf("--- End of trace buffer ---\n"); 46472755Sjhb return (0); 46572755Sjhb } 466147278Sjeff db_printf("%d (%p", tstate.cur, kp->ktr_thread); 46770035Sjhb#ifdef SMP 468147278Sjeff db_printf(":cpu%d", kp->ktr_cpu); 46970035Sjhb#endif 470147278Sjeff db_printf(")"); 471206632Sjulian if (db_ktr_verbose >= 1) { 472206632Sjulian db_printf(" %10.10lld", (long long)kp->ktr_timestamp); 47393503Sjake } 474206632Sjulian if (db_ktr_verbose >= 2) { 475206632Sjulian db_printf(" %s.%d", kp->ktr_file, kp->ktr_line); 476206632Sjulian } 477147278Sjeff db_printf(": "); 47893503Sjake db_printf(kp->ktr_desc, kp->ktr_parms[0], kp->ktr_parms[1], 47993503Sjake kp->ktr_parms[2], kp->ktr_parms[3], kp->ktr_parms[4], 48093503Sjake kp->ktr_parms[5]); 48172755Sjhb db_printf("\n"); 48270035Sjhb 48370035Sjhb if (tstate.first == -1) 48470035Sjhb tstate.first = tstate.cur; 48570035Sjhb 48670035Sjhb if (--tstate.cur < 0) 487243046Sjeff tstate.cur = ktr_entries - 1; 48870035Sjhb 48970035Sjhb return (1); 49070035Sjhb} 49170035Sjhb 49270035Sjhb#endif /* DDB */ 493