ktr changes to improve performance and make writing a userland utility to
dump the trace buffer feasible. - Remove KTR_EXTEND. This changes the format of the trace entries when activated, making writing a userland tool which is not tied to a specific kernel configuration difficult. - Use get_cyclecount() for timestamps. nanotime() is much too heavy weight and requires recursion protection due to ktr traces occuring as a result of ktr traces. KTR_VERBOSE may still require recursion protection, which is now conditional on it. - Allow KTR_CPU to be overridden by MD code. This is so that it is possible to trace early in startup before pcpu and/or curthread are setup. - Add a version number for the ktr interface. A userland tool can check this to detect mismatches. - Use an array for the parameters to make decoding in userland easier. - Add file and line recording to the non-extended traces now that the extended version is no more. These changes will break gdb macros to decode the extended version of the trace buffer which are floating around. Users of these macros should either use the show ktr command in ddb, or use the userland utility which can be run on a core dump. Approved by: jhb Tested on: i386, sparc64
This commit is contained in:
parent
e5319c69a4
commit
60a57b73ef
@ -495,7 +495,6 @@ KTR_MASK opt_ktr.h
|
||||
KTR_CPUMASK opt_ktr.h
|
||||
KTR_COMPILE opt_global.h
|
||||
KTR_ENTRIES opt_global.h
|
||||
KTR_EXTEND opt_global.h
|
||||
KTR_VERBOSE opt_ktr.h
|
||||
MUTEX_DEBUG opt_global.h
|
||||
WITNESS opt_global.h
|
||||
|
@ -46,7 +46,8 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
@ -62,22 +63,12 @@
|
||||
#define KTR_CPUMASK (~0)
|
||||
#endif
|
||||
|
||||
#ifdef SMP
|
||||
#define KTR_CPU PCPU_GET(cpuid)
|
||||
#else
|
||||
#define KTR_CPU 0
|
||||
#ifndef KTR_TIME
|
||||
#define KTR_TIME get_cyclecount()
|
||||
#endif
|
||||
|
||||
#ifdef KTR_EXTEND
|
||||
#define KTR_EXTEND_DEFAULT 1
|
||||
#else
|
||||
#define KTR_EXTEND_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#ifdef KTR_VERBOSE
|
||||
#define KTR_VERBOSE_DEFAULT 1
|
||||
#else
|
||||
#define KTR_VERBOSE_DEFAULT 0
|
||||
#ifndef KTR_CPU
|
||||
#define KTR_CPU PCPU_GET(cpuid)
|
||||
#endif
|
||||
|
||||
SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options");
|
||||
@ -86,9 +77,6 @@ SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RD, 0, "KTR options");
|
||||
* This variable is used only by gdb to work out what fields are in
|
||||
* ktr_entry.
|
||||
*/
|
||||
int ktr_extend = KTR_EXTEND_DEFAULT;
|
||||
SYSCTL_INT(_debug_ktr, OID_AUTO, extend, CTLFLAG_RD, &ktr_extend, 0, "");
|
||||
|
||||
int ktr_cpumask = KTR_CPUMASK;
|
||||
TUNABLE_INT("debug.ktr.cpumask", &ktr_cpumask);
|
||||
SYSCTL_INT(_debug_ktr, OID_AUTO, cpumask, CTLFLAG_RW, &ktr_cpumask, 0, "");
|
||||
@ -100,77 +88,75 @@ SYSCTL_INT(_debug_ktr, OID_AUTO, mask, CTLFLAG_RW, &ktr_mask, 0, "");
|
||||
int ktr_entries = KTR_ENTRIES;
|
||||
SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD, &ktr_entries, 0, "");
|
||||
|
||||
int ktr_version = KTR_VERSION;
|
||||
SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, &ktr_version, 0, "");
|
||||
|
||||
volatile int ktr_idx = 0;
|
||||
struct ktr_entry ktr_buf[KTR_ENTRIES];
|
||||
|
||||
int ktr_verbose = KTR_VERBOSE_DEFAULT;
|
||||
#ifdef KTR_VERBOSE
|
||||
int ktr_verbose = KTR_VERBOSE;
|
||||
TUNABLE_INT("debug.ktr.verbose", &ktr_verbose);
|
||||
SYSCTL_INT(_debug_ktr, OID_AUTO, verbose, CTLFLAG_RW, &ktr_verbose, 0, "");
|
||||
|
||||
#ifdef KTR
|
||||
#ifdef KTR_EXTEND
|
||||
void
|
||||
ktr_tracepoint(u_int mask, const char *filename, u_int line,
|
||||
const char *format, ...)
|
||||
#else
|
||||
void
|
||||
ktr_tracepoint(u_int mask, const char *format, u_long arg1, u_long arg2,
|
||||
u_long arg3, u_long arg4, u_long arg5, u_long arg6)
|
||||
#endif
|
||||
|
||||
void
|
||||
ktr_tracepoint(u_int mask, const char *file, int line, const char *format,
|
||||
u_long arg1, u_long arg2, u_long arg3, u_long arg4, u_long arg5,
|
||||
u_long arg6)
|
||||
{
|
||||
struct ktr_entry *entry;
|
||||
int newindex, saveindex;
|
||||
#ifdef KTR_VERBOSE
|
||||
struct thread *td;
|
||||
int cpu;
|
||||
#ifdef KTR_EXTEND
|
||||
va_list ap;
|
||||
#endif
|
||||
int cpu;
|
||||
|
||||
if (panicstr)
|
||||
return;
|
||||
if ((ktr_mask & mask) == 0)
|
||||
return;
|
||||
td = curthread;
|
||||
if (td->td_inktr)
|
||||
return;
|
||||
cpu = KTR_CPU;
|
||||
if (((1 << cpu) & ktr_cpumask) == 0)
|
||||
return;
|
||||
#ifdef KTR_VERBOSE
|
||||
td = curthread;
|
||||
if (td->td_inktr)
|
||||
return;
|
||||
td->td_inktr++;
|
||||
#endif
|
||||
do {
|
||||
saveindex = ktr_idx;
|
||||
newindex = (saveindex + 1) & (KTR_ENTRIES - 1);
|
||||
} while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0);
|
||||
entry = &ktr_buf[saveindex];
|
||||
entry->ktr_timestamp = KTR_TIME;
|
||||
entry->ktr_cpu = cpu;
|
||||
nanotime(&entry->ktr_tv);
|
||||
#ifdef KTR_EXTEND
|
||||
entry->ktr_filename = filename;
|
||||
entry->ktr_file = file;
|
||||
entry->ktr_line = line;
|
||||
va_start(ap, format);
|
||||
vsnprintf(entry->ktr_desc, KTRDESCSIZE, format, ap);
|
||||
va_end(ap);
|
||||
#ifdef KTR_VERBOSE
|
||||
if (ktr_verbose) {
|
||||
#ifdef SMP
|
||||
printf("cpu%d ", entry->ktr_cpu);
|
||||
printf("cpu%d ", cpu);
|
||||
#endif
|
||||
if (ktr_verbose > 1)
|
||||
printf("%s.%d\t", entry->ktr_filename, entry->ktr_line);
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
if (ktr_verbose > 1) {
|
||||
printf("%s.%d\t", entry->ktr_file,
|
||||
entry->ktr_line);
|
||||
}
|
||||
printf(format, arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
printf("\n");
|
||||
va_end(ap);
|
||||
}
|
||||
#else
|
||||
entry->ktr_desc = format;
|
||||
entry->ktr_parm1 = arg1;
|
||||
entry->ktr_parm2 = arg2;
|
||||
entry->ktr_parm3 = arg3;
|
||||
entry->ktr_parm4 = arg4;
|
||||
entry->ktr_parm5 = arg5;
|
||||
entry->ktr_parm6 = arg6;
|
||||
#endif
|
||||
entry->ktr_desc = format;
|
||||
entry->ktr_parms[0] = arg1;
|
||||
entry->ktr_parms[1] = arg2;
|
||||
entry->ktr_parms[2] = arg3;
|
||||
entry->ktr_parms[3] = arg4;
|
||||
entry->ktr_parms[4] = arg5;
|
||||
entry->ktr_parms[5] = arg6;
|
||||
#ifdef KTR_VERBOSE
|
||||
td->td_inktr--;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
@ -227,29 +213,21 @@ db_mach_vtrace(void)
|
||||
kp = &ktr_buf[tstate.cur];
|
||||
|
||||
/* Skip over unused entries. */
|
||||
#ifdef KTR_EXTEND
|
||||
if (kp->ktr_desc[0] == '\0') {
|
||||
#else
|
||||
if (kp->ktr_desc == NULL) {
|
||||
#endif
|
||||
db_printf("--- End of trace buffer ---\n");
|
||||
return (0);
|
||||
}
|
||||
db_printf("%d: ", tstate.cur);
|
||||
if (db_ktr_verbose)
|
||||
db_printf("%4ld.%06ld ", (long)kp->ktr_tv.tv_sec,
|
||||
kp->ktr_tv.tv_nsec / 1000);
|
||||
#ifdef KTR_EXTEND
|
||||
#ifdef SMP
|
||||
db_printf("cpu%d ", kp->ktr_cpu);
|
||||
#endif
|
||||
if (db_ktr_verbose)
|
||||
db_printf("%s.%d\t", kp->ktr_filename, kp->ktr_line);
|
||||
db_printf("%s", kp->ktr_desc);
|
||||
#else
|
||||
db_printf(kp->ktr_desc, kp->ktr_parm1, kp->ktr_parm2, kp->ktr_parm3,
|
||||
kp->ktr_parm4, kp->ktr_parm5, kp->ktr_parm6);
|
||||
#endif
|
||||
if (db_ktr_verbose) {
|
||||
db_printf("%10.10lld %s.%d\t", (long long)kp->ktr_timestamp,
|
||||
kp->ktr_file, kp->ktr_line);
|
||||
}
|
||||
db_printf(kp->ktr_desc, kp->ktr_parms[0], kp->ktr_parms[1],
|
||||
kp->ktr_parms[2], kp->ktr_parms[3], kp->ktr_parms[4],
|
||||
kp->ktr_parms[5]);
|
||||
db_printf("\n");
|
||||
|
||||
if (tstate.first == -1)
|
||||
@ -262,4 +240,3 @@ db_mach_vtrace(void)
|
||||
}
|
||||
|
||||
#endif /* DDB */
|
||||
#endif /* KTR */
|
||||
|
@ -134,12 +134,13 @@ ASSYM(KTR_CT8, KTR_CT8);
|
||||
ASSYM(KTR_SIZEOF, sizeof(struct ktr_entry));
|
||||
ASSYM(KTR_DESC, offsetof(struct ktr_entry, ktr_desc));
|
||||
ASSYM(KTR_CPU, offsetof(struct ktr_entry, ktr_cpu));
|
||||
ASSYM(KTR_PARM1, offsetof(struct ktr_entry, ktr_parm1));
|
||||
ASSYM(KTR_PARM2, offsetof(struct ktr_entry, ktr_parm2));
|
||||
ASSYM(KTR_PARM3, offsetof(struct ktr_entry, ktr_parm3));
|
||||
ASSYM(KTR_PARM4, offsetof(struct ktr_entry, ktr_parm4));
|
||||
ASSYM(KTR_PARM5, offsetof(struct ktr_entry, ktr_parm5));
|
||||
ASSYM(KTR_PARM6, offsetof(struct ktr_entry, ktr_parm6));
|
||||
ASSYM(KTR_TIMESTAMP, offsetof(struct ktr_entry, ktr_timestamp));
|
||||
ASSYM(KTR_PARM1, offsetof(struct ktr_entry, ktr_parms[0]));
|
||||
ASSYM(KTR_PARM2, offsetof(struct ktr_entry, ktr_parms[1]));
|
||||
ASSYM(KTR_PARM3, offsetof(struct ktr_entry, ktr_parms[2]));
|
||||
ASSYM(KTR_PARM4, offsetof(struct ktr_entry, ktr_parms[3]));
|
||||
ASSYM(KTR_PARM5, offsetof(struct ktr_entry, ktr_parms[4]));
|
||||
ASSYM(KTR_PARM6, offsetof(struct ktr_entry, ktr_parms[5]));
|
||||
|
||||
ASSYM(TTE_VPN, offsetof(struct tte, tte_vpn));
|
||||
ASSYM(TTE_DATA, offsetof(struct tte, tte_data));
|
||||
|
@ -36,11 +36,6 @@
|
||||
#ifndef _SYS_KTR_H_
|
||||
#define _SYS_KTR_H_
|
||||
|
||||
/* Requires sys/types.h, sys/time.h, machine/atomic.h, and machine/cpufunc.h */
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
/*
|
||||
* Hack around due to egcs-1.1.2 not knowing what __func__ is.
|
||||
*/
|
||||
@ -96,35 +91,25 @@
|
||||
#define KTR_COMPILE (KTR_GEN)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version number for ktr_entry struct. Increment this when you break binary
|
||||
* compatibility.
|
||||
*/
|
||||
#define KTR_VERSION 1
|
||||
|
||||
#define KTR_PARMS 6
|
||||
|
||||
#ifndef LOCORE
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef KTRDESCSIZE
|
||||
#define KTRDESCSIZE 80
|
||||
#endif
|
||||
|
||||
struct ktr_entry {
|
||||
struct timespec ktr_tv;
|
||||
u_int64_t ktr_timestamp;
|
||||
int ktr_cpu;
|
||||
#ifdef KTR_EXTEND
|
||||
char ktr_desc[KTRDESCSIZE];
|
||||
const char *ktr_filename;
|
||||
int ktr_line;
|
||||
#else
|
||||
const char *ktr_file;
|
||||
const char *ktr_desc;
|
||||
u_long ktr_parm1;
|
||||
u_long ktr_parm2;
|
||||
u_long ktr_parm3;
|
||||
u_long ktr_parm4;
|
||||
u_long ktr_parm5;
|
||||
u_long ktr_parm6;
|
||||
#endif
|
||||
u_long ktr_parms[KTR_PARMS];
|
||||
};
|
||||
|
||||
/* These variables are used by gdb to analyse the output */
|
||||
extern int ktr_extend;
|
||||
|
||||
extern int ktr_cpumask;
|
||||
extern int ktr_mask;
|
||||
extern int ktr_entries;
|
||||
@ -136,34 +121,15 @@ extern struct ktr_entry ktr_buf[];
|
||||
#endif /* !LOCORE */
|
||||
#ifdef KTR
|
||||
|
||||
#ifdef KTR_EXTEND
|
||||
void ktr_tracepoint(u_int mask, const char *filename, u_int line,
|
||||
const char *format, ...) __printflike(4, 5);
|
||||
#else
|
||||
void ktr_tracepoint(u_int mask, const char *format, u_long arg1, u_long arg2,
|
||||
u_long arg3, u_long arg4, u_long arg5, u_long arg6);
|
||||
#endif
|
||||
void ktr_tracepoint(u_int mask, const char *file, int line,
|
||||
const char *format, u_long arg1, u_long arg2, u_long arg3,
|
||||
u_long arg4, u_long arg5, u_long arg6);
|
||||
|
||||
#ifdef KTR_EXTEND
|
||||
#define CTR(m, format, args...) do { \
|
||||
if (KTR_COMPILE & (m)) \
|
||||
ktr_tracepoint((m), __FILE__, __LINE__, format , ##args); \
|
||||
} while(0)
|
||||
|
||||
#define CTR0(m, format) CTR(m, format)
|
||||
#define CTR1(m, format, p1) CTR(m, format, p1)
|
||||
#define CTR2(m, format, p1, p2) CTR(m, format, p1, p2)
|
||||
#define CTR3(m, format, p1, p2, p3) CTR(m, format, p1, p2, p3)
|
||||
#define CTR4(m, format, p1, p2, p3, p4) CTR(m, format, p1, p2, p3, p4)
|
||||
#define CTR5(m, format, p1, p2, p3, p4, p5) \
|
||||
CTR(m, format, p1, p2, p3, p4, p5)
|
||||
#define CTR6(m, format, p1, p2, p3, p4, p5, p6) \
|
||||
CTR(m, format, p1, p2, p3, p4, p5, p6)
|
||||
#else /* not extended */
|
||||
#define CTR6(m, format, p1, p2, p3, p4, p5, p6) do { \
|
||||
if (KTR_COMPILE & (m)) \
|
||||
ktr_tracepoint((m), format, (u_long)p1, (u_long)p2, \
|
||||
(u_long)p3, (u_long)p4, (u_long)p5, (u_long)p6); \
|
||||
ktr_tracepoint((m), __FILE__, __LINE__, format, \
|
||||
(u_long)p1, (u_long)p2, (u_long)p3, (u_long)p4, \
|
||||
(u_long)p5, (u_long)p6); \
|
||||
} while(0)
|
||||
#define CTR0(m, format) CTR6(m, format, 0, 0, 0, 0, 0, 0)
|
||||
#define CTR1(m, format, p1) CTR6(m, format, p1, 0, 0, 0, 0, 0)
|
||||
@ -171,7 +137,6 @@ void ktr_tracepoint(u_int mask, const char *format, u_long arg1, u_long arg2,
|
||||
#define CTR3(m, format, p1, p2, p3) CTR6(m, format, p1, p2, p3, 0, 0, 0)
|
||||
#define CTR4(m, format, p1, p2, p3, p4) CTR6(m, format, p1, p2, p3, p4, 0, 0)
|
||||
#define CTR5(m, format, p1, p2, p3, p4, p5) CTR6(m, format, p1, p2, p3, p4, p5, 0)
|
||||
#endif /* KTR_EXTEND */
|
||||
#else /* KTR */
|
||||
#undef KTR_COMPILE
|
||||
#define KTR_COMPILE 0
|
||||
|
Loading…
Reference in New Issue
Block a user