nrelease - fix/improve livecd
[dragonfly.git] / sys / kern / kern_ktr.c
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  *
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  */
64
65 /*
66  * Kernel tracepoint facility.
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>
75 #include <sys/libkern.h>
76 #include <sys/proc.h>
77 #include <sys/sysctl.h>
78 #include <sys/ktr.h>
79 #include <sys/systm.h>
80 #include <sys/time.h>
81 #include <sys/malloc.h>
82 #include <sys/spinlock.h>
83 #include <sys/kbio.h>
84 #include <sys/ctype.h>
85 #include <sys/limits.h>
86
87 #include <sys/thread2.h>
88 #include <sys/spinlock2.h>
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
98 #define KTR_ENTRIES             2048
99 #elif (KTR_ENTRIES & KTR_ENTRIES - 1)
100 #error KTR_ENTRIES must be a power of two
101 #endif
102 #define KTR_ENTRIES_MASK        (KTR_ENTRIES - 1)
103
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
118 /*
119  * test logging support.  When ktr_testlogcnt is non-zero each synchronization
120  * interrupt will issue six back-to-back ktr logging messages on cpu 0
121  * so the user can determine KTR logging overheads.
122  */
123 #if !defined(KTR_TESTLOG)
124 #define KTR_TESTLOG     KTR_ALL
125 #endif
126 KTR_INFO_MASTER(testlog);
127 #if KTR_TESTLOG
128 KTR_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);
133 KTR_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);
138 KTR_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);
143 KTR_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);
148 KTR_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);
153 KTR_INFO(KTR_TESTLOG, testlog, ptrdifffmt, 5,
154     "ptrdifffmt %td %ti\n",
155     ptrdiff_t d1, ptrdiff_t d2);
156 KTR_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);
161 KTR_INFO(KTR_TESTLOG, testlog, pingpong, 17, "pingpong");
162 KTR_INFO(KTR_TESTLOG, testlog, pipeline, 18, "pipeline");
163 KTR_INFO(KTR_TESTLOG, testlog, crit_beg, 19, "crit_beg");
164 KTR_INFO(KTR_TESTLOG, testlog, crit_end, 20, "crit_end");
165 KTR_INFO(KTR_TESTLOG, testlog, spin_beg, 21, "spin_beg");
166 KTR_INFO(KTR_TESTLOG, testlog, spin_end, 22, "spin_end");
167 #define logtest_noargs(name)    KTR_LOG(testlog_ ## name)
168 #endif
169
170 MALLOC_DEFINE(M_KTR, "ktr", "ktr buffers");
171
172 SYSCTL_NODE(_debug, OID_AUTO, ktr, CTLFLAG_RW, 0, "ktr");
173
174 static int      ktr_entries = KTR_ENTRIES_BOOT0;
175 SYSCTL_INT(_debug_ktr, OID_AUTO, entries, CTLFLAG_RD, &ktr_entries, 0,
176     "Size of the event buffer");
177 static int      ktr_entries_mask = KTR_ENTRIES_BOOT0_MASK;
178
179 static int      ktr_version = KTR_VERSION;
180 SYSCTL_INT(_debug_ktr, OID_AUTO, version, CTLFLAG_RD, &ktr_version, 0, "");
181
182 static int      ktr_stacktrace = 1;
183 SYSCTL_INT(_debug_ktr, OID_AUTO, stacktrace, CTLFLAG_RD, &ktr_stacktrace, 0, "");
184
185 static int      ktr_resynchronize = 0;
186 SYSCTL_INT(_debug_ktr, OID_AUTO, resynchronize, CTLFLAG_RW,
187     &ktr_resynchronize, 0, "Resynchronize TSC 10 times a second");
188
189 #if KTR_TESTLOG
190 static int      ktr_testlogcnt = 0;
191 SYSCTL_INT(_debug_ktr, OID_AUTO, testlogcnt, CTLFLAG_RW, &ktr_testlogcnt, 0, "");
192 static int      ktr_testipicnt = 0;
193 static int      ktr_testipicnt_remainder;
194 SYSCTL_INT(_debug_ktr, OID_AUTO, testipicnt, CTLFLAG_RW, &ktr_testipicnt, 0, "");
195 static int      ktr_testcritcnt = 0;
196 SYSCTL_INT(_debug_ktr, OID_AUTO, testcritcnt, CTLFLAG_RW, &ktr_testcritcnt, 0, "");
197 static int      ktr_testspincnt = 0;
198 SYSCTL_INT(_debug_ktr, OID_AUTO, testspincnt, CTLFLAG_RW, &ktr_testspincnt, 0, "");
199 #endif
200
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  */
205 static struct   ktr_entry ktr_buf0[KTR_ENTRIES_BOOT0];
206
207 struct ktr_cpu ktr_cpu[MAXCPU] = {
208         { .core.ktr_buf = &ktr_buf0[0] }
209 };
210
211 static int64_t  ktr_sync_tsc;
212 struct callout  ktr_resync_callout;
213
214 #ifdef KTR_VERBOSE
215 int     ktr_verbose = KTR_VERBOSE;
216 TUNABLE_INT("debug.ktr.verbose", &ktr_verbose);
217 SYSCTL_INT(_debug_ktr, OID_AUTO, verbose, CTLFLAG_RW, &ktr_verbose, 0,
218     "Log events to the console as well");
219 #endif
220
221 static void ktr_resync_callback(void *dummy __unused);
222
223 extern int64_t tsc_offsets[];
224
225 static void
226 ktr_sysinit(void *dummy)
227 {
228         struct ktr_cpu_core *kcpu;
229         int i;
230
231         for (i = 0; i < ncpus; ++i) {
232                 kcpu = &ktr_cpu[i].core;
233                 kcpu->ktr_buf = kmalloc(KTR_ENTRIES * sizeof(struct ktr_entry),
234                                         M_KTR, M_WAITOK | M_ZERO);
235                 if (i == 0) {
236                         /* Migrate ktrs on CPU0 to the new location */
237                         memcpy(kcpu->ktr_buf, ktr_buf0, sizeof(ktr_buf0));
238                 }
239         }
240         cpu_sfence();
241         ktr_entries = KTR_ENTRIES;
242         ktr_entries_mask = KTR_ENTRIES_MASK;
243
244         callout_init_mp(&ktr_resync_callout);
245         callout_reset(&ktr_resync_callout, hz / 10, ktr_resync_callback, NULL);
246 }
247 SYSINIT(ktr_sysinit, SI_BOOT2_KLD, SI_ORDER_ANY, ktr_sysinit, NULL);
248
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  */
258 #if KTR_TESTLOG
259 static void ktr_pingpong_remote(void *dummy);
260 static void ktr_pipeline_remote(void *dummy);
261 #endif
262
263 #ifdef _RDTSC_SUPPORTED_
264
265 static void ktr_resync_remote(void *dummy);
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  */
272 static
273 void 
274 ktr_resync_callback(void *dummy __unused)
275 {
276         struct lwkt_cpusync cs;
277 #if KTR_TESTLOG
278         int count;
279 #endif
280
281         KKASSERT(mycpu->gd_cpuid == 0);
282
283 #if KTR_TESTLOG
284         /*
285          * Test logging
286          */
287         if (ktr_testlogcnt) {
288                 --ktr_testlogcnt;
289                 cpu_disable_intr();
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);
316                 cpu_enable_intr();
317         }
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         }
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
349                 spin_init(&spin, "ktrresync");
350                 spin_lock(&spin);
351                 spin_unlock(&spin);
352                 logtest_noargs(spin_beg);
353                 for (count = ktr_testspincnt; count; --count) {
354                         spin_lock(&spin);
355                         spin_unlock(&spin);
356                 }
357                 logtest_noargs(spin_end);
358                 ktr_testspincnt = 0;
359         }
360 #endif
361
362         /*
363          * Resynchronize the TSC
364          */
365         if (ktr_resynchronize == 0)
366                 goto done;
367         if ((cpu_feature & CPUID_TSC) == 0)
368                 return;
369
370         crit_enter();
371         lwkt_cpusync_init(&cs, smp_active_mask, ktr_resync_remote,
372                           (void *)(intptr_t)mycpu->gd_cpuid);
373         lwkt_cpusync_interlock(&cs);
374         ktr_sync_tsc = rdtsc();
375         lwkt_cpusync_deinterlock(&cs);
376         crit_exit();
377 done:
378         callout_reset(&ktr_resync_callout, hz / 10, ktr_resync_callback, NULL);
379 }
380
381 /*
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).
389  */
390 static void
391 ktr_resync_remote(void *arg)
392 {
393         globaldata_t gd = mycpu;
394         int64_t delta;
395         int i;
396
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;
406         }
407 }
408
409 #if KTR_TESTLOG
410
411 static
412 void
413 ktr_pingpong_remote(void *dummy __unused)
414 {
415         int other_cpu;
416
417         logtest_noargs(pingpong);
418         other_cpu = 1 - mycpu->gd_cpuid;
419         if (ktr_testipicnt_remainder) {
420                 --ktr_testipicnt_remainder;
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);
428         }
429 }
430
431 static
432 void
433 ktr_pipeline_remote(void *dummy __unused)
434 {
435         logtest_noargs(pipeline);
436 }
437
438 #endif
439
440 #else   /* !_RDTSC_SUPPORTED_ */
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  */
447 static
448 void 
449 ktr_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();
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);
484                 cpu_enable_intr();
485         }
486         callout_reset(&ktr_resync_callout, hz / 10, ktr_resync_callback, NULL);
487 #endif
488 }
489
490 #endif
491
492 /*
493  * Setup the next empty slot and return it to the caller to store the data
494  * directly.
495  */
496 struct ktr_entry *
497 ktr_begin_write_entry(struct ktr_info *info, const char *file, int line)
498 {
499         struct ktr_cpu_core *kcpu;
500         struct ktr_entry *entry;
501         int cpu;
502
503         cpu = mycpu->gd_cpuid;
504         kcpu = &ktr_cpu[cpu].core;
505         if (panicstr)                   /* stop logging during panic */
506                 return NULL;
507         if (kcpu->ktr_buf == NULL)      /* too early in boot */
508                 return NULL;
509
510         crit_enter();
511         entry = kcpu->ktr_buf + (kcpu->ktr_idx & ktr_entries_mask);
512         ++kcpu->ktr_idx;
513 #ifdef _RDTSC_SUPPORTED_
514         if (cpu_feature & CPUID_TSC) {
515                 entry->ktr_timestamp = rdtsc() - tsc_offsets[cpu];
516         } else
517 #endif
518         {
519                 entry->ktr_timestamp = get_approximate_time_t();
520         }
521         entry->ktr_info = info;
522         entry->ktr_file = file;
523         entry->ktr_line = line;
524         crit_exit();
525         return entry;
526 }
527
528 int
529 ktr_finish_write_entry(struct ktr_info *info, struct ktr_entry *entry)
530 {
531         if (ktr_stacktrace)
532                 cpu_ktr_caller(entry);
533 #ifdef KTR_VERBOSE
534         if (ktr_verbose && info->kf_format) {
535                 kprintf("cpu%d ", mycpu->gd_cpuid);
536                 if (ktr_verbose > 1) {
537                         kprintf("%s.%d\t", entry->ktr_file, entry->ktr_line);
538                 }
539                 return !0;
540         }
541 #endif
542         return 0;
543 }
544
545 #ifdef DDB
546
547 #define NUM_LINES_PER_PAGE      19
548
549 struct tstate {
550         int     cur;
551         int     first;
552 };
553
554 static  int db_ktr_verbose;
555 static  int db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx);
556
557 DB_SHOW_COMMAND(ktr, db_ktr_all)
558 {
559         struct ktr_cpu_core *kcpu;
560         int a_flag = 0;
561         int c;
562         int nl = 0;
563         int i;
564         struct tstate tstate[MAXCPU];
565         int printcpu = -1;
566
567         for(i = 0; i < ncpus; i++) {
568                 kcpu = &ktr_cpu[i].core;
569                 tstate[i].first = -1;
570                 tstate[i].cur = (kcpu->ktr_idx - 1) & ktr_entries_mask;
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;
579                 }
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--;
593                 }
594         }
595         if (printcpu > ncpus - 1) {
596                 db_printf("Invalid cpu number\n");
597                 return;
598         }
599         /*
600          * Loop throug all the buffers and print the content of them, sorted
601          * by the timestamp.
602          */
603         while (1) {
604                 int counter;
605                 u_int64_t highest_ts;
606                 struct ktr_entry *kp;
607                 int highest_cpu;
608                 int c;
609
610                 if (a_flag == 1) {
611                         c = cncheckc();
612                         if (c != -1 && c != NOKEY)
613                                 return;
614                 }
615                 highest_ts = 0;
616                 highest_cpu = -1;
617                 /*
618                  * Find the lowest timestamp
619                  */
620                 for (i = 0, counter = 0; i < ncpus; i++) {
621                         kcpu = &ktr_cpu[i].core;
622                         if (kcpu->ktr_buf == NULL)
623                                 continue;
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                         }
634                         if (kcpu->ktr_buf[tstate[i].cur].ktr_timestamp > highest_ts) {
635                                 highest_ts = kcpu->ktr_buf[tstate[i].cur].ktr_timestamp;
636                                 highest_cpu = i;
637                         }
638                 }
639                 if (highest_cpu < 0) {
640                         db_printf("no KTR data available\n");
641                         break;
642                 }
643                 i = highest_cpu;
644                 kcpu = &ktr_cpu[i].core;
645                 kp = &kcpu->ktr_buf[tstate[i].cur];
646                 if (tstate[i].first == -1)
647                         tstate[i].first = tstate[i].cur;
648                 if (--tstate[i].cur < 0)
649                         tstate[i].cur = ktr_entries - 1;
650                 if (tstate[i].first == tstate[i].cur) {
651                         db_mach_vtrace(i, kp, tstate[i].cur + 1);
652                         tstate[i].cur = -1;
653                         continue;
654                 }
655                 if (kcpu->ktr_buf[tstate[i].cur].ktr_info == NULL)
656                         tstate[i].cur = -1;
657                 if (db_more(&nl) == -1)
658                         break;
659                 if (db_mach_vtrace(i, kp, tstate[i].cur + 1) == 0)
660                         tstate[i].cur = -1;
661         }
662 }
663
664 static int
665 db_mach_vtrace(int cpu, struct ktr_entry *kp, int idx)
666 {
667         if (kp->ktr_info == NULL)
668                 return(0);
669         db_printf("cpu%d ", cpu);
670         db_printf("%d: ", idx);
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         }
675         db_printf("%s\t", kp->ktr_info->kf_name);
676         db_printf("from(%p,%p) ", kp->ktr_caller1, kp->ktr_caller2);
677         db_printf("\n");
678
679         return(1);
680 }
681
682 #endif  /* DDB */