nrelease - fix/improve livecd
[dragonfly.git] / sys / kern / kern_ktr.c
CommitLineData
d3776285
MD
1/*
2 * Copyright (c) 2005 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34/*
35 * The following copyright applies to the DDB command code:
36 *
81540c2d
EN
37 * Copyright (c) 2000 John Baldwin <jhb@FreeBSD.org>
38 * All rights reserved.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the author nor the names of any co-contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 */
6d22945a 64
81540c2d 65/*
d3776285 66 * Kernel tracepoint facility.
81540c2d
EN
67 */
68
69#include "opt_ddb.h"
70#include "opt_ktr.h"
71
72#include <sys/param.h>
73#include <sys/cons.h>
74#include <sys/kernel.h>
81540c2d
EN
75#include <sys/libkern.h>
76#include <sys/proc.h>
77#include <sys/sysctl.h>
d3776285 78#include <sys/ktr.h>
81540c2d
EN
79#include <sys/systm.h>
80#include <sys/time.h>
8e273a1d 81#include <sys/malloc.h>
c2751817 82#include <sys/spinlock.h>
ce7866b8
MD
83#include <sys/kbio.h>
84#include <sys/ctype.h>
2fa6678b 85#include <sys/limits.h>
ce7866b8 86
8e273a1d 87#include <sys/thread2.h>
c2751817 88#include <sys/spinlock2.h>
81540c2d
EN
89
90#include <machine/cpu.h>
91#include <machine/cpufunc.h>
92#include <machine/specialreg.h>
93#include <machine/md_var.h>
94
95#include <ddb/ddb.h>
96
97#ifndef KTR_ENTRIES
d3776285 98#define KTR_ENTRIES 2048
6d22945a
SW
99#elif (KTR_ENTRIES & KTR_ENTRIES - 1)
100#error KTR_ENTRIES must be a power of two
81540c2d 101#endif
d3776285 102#define KTR_ENTRIES_MASK (KTR_ENTRIES - 1)
81540c2d 103
62b18938
SZ
104/*
105 * Used by earlier boot; default value consumes ~64K BSS.
106 *
107 * NOTE:
108 * We use a small value here; this prevents kernel or module loading
109 * failure due to excessive BSS usage if KTR_ENTRIES is large.
110 */
111#if (KTR_ENTRIES < 256)
112#define KTR_ENTRIES_BOOT0 KTR_ENTRIES
113#else
114#define KTR_ENTRIES_BOOT0 256
115#endif
116#define KTR_ENTRIES_BOOT0_MASK (KTR_ENTRIES_BOOT0 - 1)
117
96328d40
MD
118/*
119 * test logging support. When ktr_testlogcnt is non-zero each synchronization
0b698dca 120 * interrupt will issue six back-to-back ktr logging messages on cpu 0
96328d40
MD
121 * so the user can determine KTR logging overheads.
122 */
123#if !defined(KTR_TESTLOG)
124#define KTR_TESTLOG KTR_ALL
125#endif
126KTR_INFO_MASTER(testlog);
8cb417fa 127#if KTR_TESTLOG
2fa6678b
SW
128KTR_INFO(KTR_TESTLOG, testlog, charfmt, 0,
129 "charfmt %hhd %hhi %#hho %hhu %#hhx %#hhX\n",
130 signed char d1, signed char d2,
131 unsigned char d3, unsigned char d4,
132 unsigned char d5, unsigned char d6);
133KTR_INFO(KTR_TESTLOG, testlog, shortfmt, 1,
134 "shortfmt %hd %hi %#ho %hu %#hx %#hX\n",
135 short d1, short d2,
136 unsigned short d3, unsigned short d4,
137 unsigned short d5, unsigned short d6);
138KTR_INFO(KTR_TESTLOG, testlog, longfmt, 2,
139 "longfmt %ld %li %#lo %lu %#lx %#lX\n",
140 long d1, long d2,
141 unsigned long d3, unsigned long d4,
142 unsigned long d5, unsigned long d6);
143KTR_INFO(KTR_TESTLOG, testlog, longlongfmt, 3,
144 "longlongfmt %lld %lli %#llo %llu %#llx %#llX\n",
145 long long d1, long long d2,
146 unsigned long long d3, unsigned long long d4,
147 unsigned long long d5, unsigned long long d6);
148KTR_INFO(KTR_TESTLOG, testlog, intmaxfmt, 4,
149 "intmaxfmt %jd %ji %#jo %ju %#jx %#jX\n",
150 intmax_t d1, intmax_t d2,
151 uintmax_t d3, uintmax_t d4,
152 uintmax_t d5, uintmax_t d6);
153KTR_INFO(KTR_TESTLOG, testlog, ptrdifffmt, 5,
154 "ptrdifffmt %td %ti\n",
155 ptrdiff_t d1, ptrdiff_t d2);
156KTR_INFO(KTR_TESTLOG, testlog, sizefmt, 6,
157 "sizefmt %zd %zi %#zo %zu %#zx %#zX\n",
158 ssize_t d1, ssize_t d2,
159 size_t d3, size_t d4,
160 size_t d5, size_t d6);
ddd22766
SW
161KTR_INFO(KTR_TESTLOG, testlog, pingpong, 17, "pingpong");
162KTR_INFO(KTR_TESTLOG, testlog, pipeline, 18, "pipeline");
163KTR_INFO(KTR_TESTLOG, testlog, crit_beg, 19, "crit_beg");
164KTR_INFO(KTR_TESTLOG, testlog, crit_end, 20, "crit_end");
165KTR_INFO(KTR_TESTLOG, testlog, spin_beg, 21, "spin_beg");
166KTR_INFO(KTR_TESTLOG, testlog, spin_end, 22, "spin_end");
0b698dca 167#define logtest_noargs(name) KTR_LOG(testlog_ ## name)
8cb417fa 168#endif
96328d40 169
8e273a1d
EN
170MALLOC_DEFINE(M_KTR, "ktr", "ktr buffers");
171
d3776285 172SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RW, 0, "ktr");
81540c2d 173
62b18938 174static int ktr_entries = KTR_ENTRIES_BOOT0;
f22af1e9
SW
175SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD, &ktr_entries, 0,
176 "Size of the event buffer");
62b18938 177static int ktr_entries_mask = KTR_ENTRIES_BOOT0_MASK;
81540c2d 178
62b18938 179static int ktr_version = KTR_VERSION;
81540c2d
EN
180SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, &ktr_version, 0, "");
181
af6ff89e
MD
182static int ktr_stacktrace = 1;
183SYSCTL_INT(_debug_ktr, OID_AUTO, stacktrace, CTLFLAG_RD, &ktr_stacktrace, 0, "");
184
374133e3 185static int ktr_resynchronize = 0;
f22af1e9
SW
186SYSCTL_INT(_debug_ktr, OID_AUTO, resynchronize, CTLFLAG_RW,
187 &ktr_resynchronize, 0, "Resynchronize TSC 10 times a second");
374133e3 188
96328d40
MD
189#if KTR_TESTLOG
190static int ktr_testlogcnt = 0;
191SYSCTL_INT(_debug_ktr, OID_AUTO, testlogcnt, CTLFLAG_RW, &ktr_testlogcnt, 0, "");
72d379df
MD
192static int ktr_testipicnt = 0;
193static int ktr_testipicnt_remainder;
194SYSCTL_INT(_debug_ktr, OID_AUTO, testipicnt, CTLFLAG_RW, &ktr_testipicnt, 0, "");
c2751817
MD
195static int ktr_testcritcnt = 0;
196SYSCTL_INT(_debug_ktr, OID_AUTO, testcritcnt, CTLFLAG_RW, &ktr_testcritcnt, 0, "");
197static int ktr_testspincnt = 0;
198SYSCTL_INT(_debug_ktr, OID_AUTO, testspincnt, CTLFLAG_RW, &ktr_testspincnt, 0, "");
96328d40
MD
199#endif
200
d3776285
MD
201/*
202 * Give cpu0 a static buffer so the tracepoint facility can be used during
203 * early boot (note however that we still use a critical section, XXX).
204 */
62b18938 205static struct ktr_entry ktr_buf0[KTR_ENTRIES_BOOT0];
ddca1582 206
02289741 207struct ktr_cpu ktr_cpu[MAXCPU] = {
ddca1582
MD
208 { .core.ktr_buf = &ktr_buf0[0] }
209};
210
374133e3
MD
211static int64_t ktr_sync_tsc;
212struct callout ktr_resync_callout;
213
81540c2d
EN
214#ifdef KTR_VERBOSE
215int ktr_verbose = KTR_VERBOSE;
216TUNABLE_INT("debug.ktr.verbose", &ktr_verbose);
f22af1e9
SW
217SYSCTL_INT(_debug_ktr, OID_AUTO, verbose, CTLFLAG_RW, &ktr_verbose, 0,
218 "Log events to the console as well");
81540c2d
EN
219#endif
220
ba39e2e0
MD
221static void ktr_resync_callback(void *dummy __unused);
222
c2751817 223extern int64_t tsc_offsets[];
0b698dca 224
81540c2d
EN
225static void
226ktr_sysinit(void *dummy)
227{
ddca1582 228 struct ktr_cpu_core *kcpu;
8e273a1d
EN
229 int i;
230
62b18938 231 for (i = 0; i < ncpus; ++i) {
ddca1582
MD
232 kcpu = &ktr_cpu[i].core;
233 kcpu->ktr_buf = kmalloc(KTR_ENTRIES * sizeof(struct ktr_entry),
234 M_KTR, M_WAITOK | M_ZERO);
62b18938
SZ
235 if (i == 0) {
236 /* Migrate ktrs on CPU0 to the new location */
237 memcpy(kcpu->ktr_buf, ktr_buf0, sizeof(ktr_buf0));
238 }
8e273a1d 239 }
62b18938
SZ
240 cpu_sfence();
241 ktr_entries = KTR_ENTRIES;
242 ktr_entries_mask = KTR_ENTRIES_MASK;
243
bf0ecf68 244 callout_init_mp(&ktr_resync_callout);
ba39e2e0 245 callout_reset(&ktr_resync_callout, hz / 10, ktr_resync_callback, NULL);
81540c2d 246}
ba39e2e0 247SYSINIT(ktr_sysinit, SI_BOOT2_KLD, SI_ORDER_ANY, ktr_sysinit, NULL);
374133e3 248
374133e3
MD
249/*
250 * Try to resynchronize the TSC's for all cpus. This is really, really nasty.
251 * We have to send an IPIQ message to all remote cpus, wait until they
252 * get into their IPIQ processing code loop, then do an even stricter hard
253 * loop to get the cpus as close to synchronized as we can to get the most
254 * accurate reading.
255 *
256 * This callback occurs on cpu0.
257 */
8cb417fa 258#if KTR_TESTLOG
72d379df 259static void ktr_pingpong_remote(void *dummy);
c2751817 260static void ktr_pipeline_remote(void *dummy);
8cb417fa 261#endif
374133e3 262
1918fc5c 263#ifdef _RDTSC_SUPPORTED_
b4c3db6f
MD
264
265static void ktr_resync_remote(void *dummy);
374133e3
MD
266
267/*
268 * We use a callout callback instead of a systimer because we cannot afford
269 * to preempt anyone to do this, or we might deadlock a spin-lock or
270 * serializer between two cpus.
271 */
272static
273void
274ktr_resync_callback(void *dummy __unused)
275{
f697b97d 276 struct lwkt_cpusync cs;
ef4b87ee 277#if KTR_TESTLOG
374133e3 278 int count;
ef4b87ee 279#endif
374133e3
MD
280
281 KKASSERT(mycpu->gd_cpuid == 0);
96328d40
MD
282
283#if KTR_TESTLOG
284 /*
285 * Test logging
286 */
287 if (ktr_testlogcnt) {
288 --ktr_testlogcnt;
289 cpu_disable_intr();
2fa6678b
SW
290 KTR_LOG(testlog_charfmt,
291 (signed char)UCHAR_MAX, (signed char)UCHAR_MAX,
292 (unsigned char)-1, (unsigned char)-1,
293 (unsigned char)-1, (unsigned char)-1);
294 KTR_LOG(testlog_shortfmt,
295 (short)USHRT_MAX, (short)USHRT_MAX,
296 (unsigned short)-1, (unsigned short)-1,
297 (unsigned short)-1, (unsigned short)-1);
298 KTR_LOG(testlog_longfmt,
299 (long)ULONG_MAX, (long)ULONG_MAX,
300 (unsigned long)-1, (unsigned long)-1,
301 (unsigned long)-1, (unsigned long)-1);
302 KTR_LOG(testlog_longlongfmt,
303 (long long)ULLONG_MAX, (long long)ULLONG_MAX,
304 (unsigned long long)-1, (unsigned long long)-1,
305 (unsigned long long)-1, (unsigned long long)-1);
306 KTR_LOG(testlog_intmaxfmt,
307 (intmax_t)UINTMAX_MAX, (intmax_t)UINTMAX_MAX,
308 (uintmax_t)-1, (uintmax_t)-1,
309 (uintmax_t)-1, (uintmax_t)-1);
310 KTR_LOG(testlog_ptrdifffmt,
311 (ptrdiff_t)PTRDIFF_MAX, (ptrdiff_t)PTRDIFF_MAX);
312 KTR_LOG(testlog_sizefmt,
313 (ssize_t)SIZE_T_MAX, (ssize_t)SIZE_T_MAX,
314 (size_t)-1, (size_t)-1,
315 (size_t)-1, (size_t)-1);
96328d40
MD
316 cpu_enable_intr();
317 }
72d379df
MD
318
319 /*
320 * Test IPI messaging
321 */
322 if (ktr_testipicnt && ktr_testipicnt_remainder == 0 && ncpus > 1) {
323 ktr_testipicnt_remainder = ktr_testipicnt;
324 ktr_testipicnt = 0;
325 lwkt_send_ipiq_bycpu(1, ktr_pingpong_remote, NULL);
326 }
c2751817
MD
327
328 /*
329 * Test critical sections
330 */
331 if (ktr_testcritcnt) {
332 crit_enter();
333 crit_exit();
334 logtest_noargs(crit_beg);
335 for (count = ktr_testcritcnt; count; --count) {
336 crit_enter();
337 crit_exit();
338 }
339 logtest_noargs(crit_end);
340 ktr_testcritcnt = 0;
341 }
342
343 /*
344 * Test spinlock sections
345 */
346 if (ktr_testspincnt) {
347 struct spinlock spin;
348
ba87a4ab 349 spin_init(&spin, "ktrresync");
287a8577
AH
350 spin_lock(&spin);
351 spin_unlock(&spin);
c2751817
MD
352 logtest_noargs(spin_beg);
353 for (count = ktr_testspincnt; count; --count) {
287a8577
AH
354 spin_lock(&spin);
355 spin_unlock(&spin);
d666840a
MD
356 }
357 logtest_noargs(spin_end);
c2751817
MD
358 ktr_testspincnt = 0;
359 }
96328d40
MD
360#endif
361
362 /*
363 * Resynchronize the TSC
364 */
374133e3
MD
365 if (ktr_resynchronize == 0)
366 goto done;
367 if ((cpu_feature & CPUID_TSC) == 0)
368 return;
0b698dca 369
374133e3 370 crit_enter();
f697b97d
MD
371 lwkt_cpusync_init(&cs, smp_active_mask, ktr_resync_remote,
372 (void *)(intptr_t)mycpu->gd_cpuid);
373 lwkt_cpusync_interlock(&cs);
374133e3 374 ktr_sync_tsc = rdtsc();
f697b97d 375 lwkt_cpusync_deinterlock(&cs);
374133e3 376 crit_exit();
374133e3
MD
377done:
378 callout_reset(&ktr_resync_callout, hz / 10, ktr_resync_callback, NULL);
379}
380
0b698dca 381/*
f697b97d
MD
382 * The remote-end of the KTR synchronization protocol runs on all cpus.
383 * The one we run on the controlling cpu updates its tsc continuously
384 * until the others have finished syncing (theoretically), but we don't
385 * loop forever.
386 *
387 * This is a bit ad-hoc but we need to avoid livelocking inside an IPI
388 * callback. rdtsc() is a synchronizing instruction (I think).
0b698dca 389 */
374133e3 390static void
f697b97d 391ktr_resync_remote(void *arg)
374133e3 392{
f697b97d
MD
393 globaldata_t gd = mycpu;
394 int64_t delta;
395 int i;
374133e3 396
f697b97d
MD
397 if (gd->gd_cpuid == (int)(intptr_t)arg) {
398 for (i = 0; i < 2000; ++i)
399 ktr_sync_tsc = rdtsc();
400 } else {
401 delta = rdtsc() - ktr_sync_tsc;
402 if (tsc_offsets[gd->gd_cpuid] == 0)
403 tsc_offsets[gd->gd_cpuid] = delta;
404 tsc_offsets[gd->gd_cpuid] =
405 (tsc_offsets[gd->gd_cpuid] * 7 + delta) / 8;
374133e3 406 }
374133e3 407}
81540c2d 408
8cb417fa
MD
409#if KTR_TESTLOG
410
72d379df
MD
411static
412void
413ktr_pingpong_remote(void *dummy __unused)
414{
c2751817
MD
415 int other_cpu;
416
72d379df 417 logtest_noargs(pingpong);
c2751817 418 other_cpu = 1 - mycpu->gd_cpuid;
72d379df
MD
419 if (ktr_testipicnt_remainder) {
420 --ktr_testipicnt_remainder;
c2751817
MD
421 lwkt_send_ipiq_bycpu(other_cpu, ktr_pingpong_remote, NULL);
422 } else {
423 lwkt_send_ipiq_bycpu(other_cpu, ktr_pipeline_remote, NULL);
424 lwkt_send_ipiq_bycpu(other_cpu, ktr_pipeline_remote, NULL);
425 lwkt_send_ipiq_bycpu(other_cpu, ktr_pipeline_remote, NULL);
426 lwkt_send_ipiq_bycpu(other_cpu, ktr_pipeline_remote, NULL);
427 lwkt_send_ipiq_bycpu(other_cpu, ktr_pipeline_remote, NULL);
72d379df
MD
428 }
429}
430
c2751817
MD
431static
432void
433ktr_pipeline_remote(void *dummy __unused)
434{
435 logtest_noargs(pipeline);
436}
437
8cb417fa
MD
438#endif
439
1918fc5c 440#else /* !_RDTSC_SUPPORTED_ */
0b698dca
MD
441
442/*
443 * The resync callback for UP doesn't do anything other then run the test
444 * log messages. If test logging is not enabled, don't bother resetting
445 * the callout.
446 */
447static
448void
449ktr_resync_callback(void *dummy __unused)
450{
451#if KTR_TESTLOG
452 /*
453 * Test logging
454 */
455 if (ktr_testlogcnt) {
456 --ktr_testlogcnt;
457 cpu_disable_intr();
2fa6678b
SW
458 KTR_LOG(testlog_charfmt,
459 (signed char)UCHAR_MAX, (signed char)UCHAR_MAX,
460 (unsigned char)-1, (unsigned char)-1,
461 (unsigned char)-1, (unsigned char)-1);
462 KTR_LOG(testlog_shortfmt,
463 (short)USHRT_MAX, (short)USHRT_MAX,
464 (unsigned short)-1, (unsigned short)-1,
465 (unsigned short)-1, (unsigned short)-1);
466 KTR_LOG(testlog_longfmt,
467 (long)ULONG_MAX, (long)ULONG_MAX,
468 (unsigned long)-1, (unsigned long)-1,
469 (unsigned long)-1, (unsigned long)-1);
470 KTR_LOG(testlog_longlongfmt,
471 (long long)ULLONG_MAX, (long long)ULLONG_MAX,
472 (unsigned long long)-1, (unsigned long long)-1,
473 (unsigned long long)-1, (unsigned long long)-1);
474 KTR_LOG(testlog_intmaxfmt,
475 (intmax_t)UINTMAX_MAX, (intmax_t)UINTMAX_MAX,
476 (uintmax_t)-1, (uintmax_t)-1,
477 (uintmax_t)-1, (uintmax_t)-1);
478 KTR_LOG(testlog_ptrdifffmt,
479 (ptrdiff_t)PTRDIFF_MAX, (ptrdiff_t)PTRDIFF_MAX);
480 KTR_LOG(testlog_sizefmt,
481 (ssize_t)SIZE_T_MAX, (ssize_t)SIZE_T_MAX,
482 (size_t)-1, (size_t)-1,
483 (size_t)-1, (size_t)-1);
0b698dca
MD
484 cpu_enable_intr();
485 }
486 callout_reset(&ktr_resync_callout, hz / 10, ktr_resync_callback, NULL);
487#endif
488}
489
374133e3 490#endif
81540c2d 491
0b698dca 492/*
5bf48697
AE
493 * Setup the next empty slot and return it to the caller to store the data
494 * directly.
0b698dca 495 */
5bf48697
AE
496struct ktr_entry *
497ktr_begin_write_entry(struct ktr_info *info, const char *file, int line)
81540c2d 498{
ddca1582 499 struct ktr_cpu_core *kcpu;
81540c2d 500 struct ktr_entry *entry;
d3776285
MD
501 int cpu;
502
503 cpu = mycpu->gd_cpuid;
ddca1582 504 kcpu = &ktr_cpu[cpu].core;
ab1b4385
MD
505 if (panicstr) /* stop logging during panic */
506 return NULL;
507 if (kcpu->ktr_buf == NULL) /* too early in boot */
5bf48697 508 return NULL;
b4cb74b5
SW
509
510 crit_enter();
62b18938 511 entry = kcpu->ktr_buf + (kcpu->ktr_idx & ktr_entries_mask);
ddca1582 512 ++kcpu->ktr_idx;
527fddf7 513#ifdef _RDTSC_SUPPORTED_
b4cb74b5 514 if (cpu_feature & CPUID_TSC) {
b4cb74b5 515 entry->ktr_timestamp = rdtsc() - tsc_offsets[cpu];
527fddf7
MD
516 } else
517#endif
518 {
b4cb74b5 519 entry->ktr_timestamp = get_approximate_time_t();
8e273a1d 520 }
b4cb74b5
SW
521 entry->ktr_info = info;
522 entry->ktr_file = file;
523 entry->ktr_line = line;
524 crit_exit();
5bf48697
AE
525 return entry;
526}
527
528int
529ktr_finish_write_entry(struct ktr_info *info, struct ktr_entry *entry)
530{
b4cb74b5
SW
531 if (ktr_stacktrace)
532 cpu_ktr_caller(entry);
81540c2d 533#ifdef KTR_VERBOSE
d3776285 534 if (ktr_verbose && info->kf_format) {
5bf48697 535 kprintf("cpu%d ", mycpu->gd_cpuid);
81540c2d 536 if (ktr_verbose > 1) {
6ea70f76 537 kprintf("%s.%d\t", entry->ktr_file, entry->ktr_line);
81540c2d 538 }
5bf48697 539 return !0;
81540c2d
EN
540 }
541#endif
5bf48697 542 return 0;
d3776285
MD
543}
544
81540c2d
EN
545#ifdef DDB
546
8e273a1d 547#define NUM_LINES_PER_PAGE 19
81540c2d
EN
548
549struct tstate {
550 int cur;
551 int first;
552};
d3776285 553
81540c2d 554static int db_ktr_verbose;
d3776285 555static int db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx);
81540c2d
EN
556
557DB_SHOW_COMMAND(ktr, db_ktr_all)
558{
ddca1582 559 struct ktr_cpu_core *kcpu;
8e273a1d
EN
560 int a_flag = 0;
561 int c;
81540c2d 562 int nl = 0;
8e273a1d
EN
563 int i;
564 struct tstate tstate[MAXCPU];
565 int printcpu = -1;
566
567 for(i = 0; i < ncpus; i++) {
ddca1582 568 kcpu = &ktr_cpu[i].core;
8e273a1d 569 tstate[i].first = -1;
62b18938 570 tstate[i].cur = (kcpu->ktr_idx - 1) & ktr_entries_mask;
8e273a1d
EN
571 }
572 db_ktr_verbose = 0;
573 while ((c = *(modif++)) != '\0') {
574 if (c == 'v') {
575 db_ktr_verbose = 1;
576 }
577 else if (c == 'a') {
578 a_flag = 1;
81540c2d 579 }
8e273a1d
EN
580 else if (c == 'c') {
581 printcpu = 0;
582 while ((c = *(modif++)) != '\0') {
583 if (isdigit(c)) {
584 printcpu *= 10;
585 printcpu += c - '0';
586 }
587 else {
588 modif++;
589 break;
590 }
591 }
592 modif--;
81540c2d
EN
593 }
594 }
8e273a1d
EN
595 if (printcpu > ncpus - 1) {
596 db_printf("Invalid cpu number\n");
597 return;
598 }
599 /*
ce7866b8 600 * Loop throug all the buffers and print the content of them, sorted
8e273a1d
EN
601 * by the timestamp.
602 */
603 while (1) {
604 int counter;
605 u_int64_t highest_ts;
8e273a1d 606 struct ktr_entry *kp;
ce7866b8
MD
607 int highest_cpu;
608 int c;
8e273a1d 609
ce7866b8
MD
610 if (a_flag == 1) {
611 c = cncheckc();
612 if (c != -1 && c != NOKEY)
613 return;
614 }
8e273a1d
EN
615 highest_ts = 0;
616 highest_cpu = -1;
617 /*
618 * Find the lowest timestamp
619 */
620 for (i = 0, counter = 0; i < ncpus; i++) {
ddca1582
MD
621 kcpu = &ktr_cpu[i].core;
622 if (kcpu->ktr_buf == NULL)
d3776285 623 continue;
8e273a1d
EN
624 if (printcpu != -1 && printcpu != i)
625 continue;
626 if (tstate[i].cur == -1) {
627 counter++;
628 if (counter == ncpus) {
629 db_printf("--- End of trace buffer ---\n");
630 return;
631 }
632 continue;
633 }
ddca1582
MD
634 if (kcpu->ktr_buf[tstate[i].cur].ktr_timestamp > highest_ts) {
635 highest_ts = kcpu->ktr_buf[tstate[i].cur].ktr_timestamp;
8e273a1d
EN
636 highest_cpu = i;
637 }
638 }
438c526f
MD
639 if (highest_cpu < 0) {
640 db_printf("no KTR data available\n");
641 break;
642 }
8e273a1d 643 i = highest_cpu;
ddca1582
MD
644 kcpu = &ktr_cpu[i].core;
645 kp = &kcpu->ktr_buf[tstate[i].cur];
8e273a1d
EN
646 if (tstate[i].first == -1)
647 tstate[i].first = tstate[i].cur;
648 if (--tstate[i].cur < 0)
62b18938 649 tstate[i].cur = ktr_entries - 1;
8e273a1d 650 if (tstate[i].first == tstate[i].cur) {
d3776285 651 db_mach_vtrace(i, kp, tstate[i].cur + 1);
8e273a1d
EN
652 tstate[i].cur = -1;
653 continue;
654 }
ddca1582 655 if (kcpu->ktr_buf[tstate[i].cur].ktr_info == NULL)
8e273a1d
EN
656 tstate[i].cur = -1;
657 if (db_more(&nl) == -1)
658 break;
d3776285 659 if (db_mach_vtrace(i, kp, tstate[i].cur + 1) == 0)
8e273a1d
EN
660 tstate[i].cur = -1;
661 }
81540c2d
EN
662}
663
664static int
d3776285 665db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx)
81540c2d 666{
d3776285 667 if (kp->ktr_info == NULL)
8e273a1d 668 return(0);
d3776285 669 db_printf("cpu%d ", cpu);
8e273a1d 670 db_printf("%d: ", idx);
81540c2d
EN
671 if (db_ktr_verbose) {
672 db_printf("%10.10lld %s.%d\t", (long long)kp->ktr_timestamp,
673 kp->ktr_file, kp->ktr_line);
674 }
d3776285 675 db_printf("%s\t", kp->ktr_info->kf_name);
af6ff89e 676 db_printf("from(%p,%p) ", kp->ktr_caller1, kp->ktr_caller2);
81540c2d
EN
677 db_printf("\n");
678
8e273a1d 679 return(1);
81540c2d
EN
680}
681
682#endif /* DDB */