FreeBSD kernel kern code
kern_boottrace.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2008-2022 NetApp, Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/param.h>
28#include <sys/systm.h>
29#include <sys/boottrace.h>
30#include <sys/kernel.h>
31#include <sys/malloc.h>
32#include <sys/pcpu.h>
33#include <sys/proc.h>
34#include <sys/resourcevar.h>
35#include <sys/sbuf.h>
36#include <sys/syscallsubr.h>
37#include <sys/sysctl.h>
38#include <sys/time.h>
39
40#include <machine/stdarg.h>
41
42#define dprintf(fmt, ...) \
43 do { \
44 if (dotrace_debugging) \
45 printf(fmt, ##__VA_ARGS__); \
46 } while (0);
47
48static MALLOC_DEFINE(M_BOOTTRACE, "boottrace", "memory for boot tracing");
49
50#define BT_TABLE_DEFSIZE 3000
51#define BT_TABLE_RUNSIZE 2000
52#define BT_TABLE_SHTSIZE 1000
53#define BT_TABLE_MINSIZE 500
54
55/*
56 * Boot-time & shutdown-time event.
57 */
58struct bt_event {
59 uint64_t tsc; /* Timestamp */
60 uint64_t tick; /* Kernel tick */
61 uint64_t cputime; /* Microseconds of process CPU time */
62 uint32_t cpuid; /* CPU on which the event ran */
63 uint32_t inblock; /* # of blocks in */
64 uint32_t oublock; /* # of blocks out */
65 pid_t pid; /* Current PID */
66 char name[BT_EVENT_NAMELEN]; /* Event name */
67 char tdname[BT_EVENT_TDNAMELEN]; /* Thread name */
68};
69
70struct bt_table {
71 uint32_t size; /* Trace table size */
72 uint32_t curr; /* Trace entry to use */
73 uint32_t wrap; /* Wrap-around, instead of dropping */
74 uint32_t drops_early; /* Trace entries dropped before init */
75 uint32_t drops_full; /* Trace entries dropped after full */
76 struct bt_event *table;
77};
78
79/* Boot-time tracing */
80static struct bt_table bt;
81
82/* Run-time tracing */
83static struct bt_table rt;
84
85/* Shutdown-time tracing */
86static struct bt_table st;
87
88/* Set when system boot is complete, and we've switched to runtime tracing. */
89static bool bootdone;
90
91/* Set when system shutdown has started. */
92static bool shutdown;
93
94/* Turn on dotrace() debug logging to console. */
96TUNABLE_BOOL("debug.boottrace.dotrace_debugging", &dotrace_debugging);
97
98/* Trace kernel events */
99static bool dotrace_kernel = true;
100TUNABLE_BOOL("kern.boottrace.dotrace_kernel", &dotrace_kernel);
101
102/* Trace userspace events */
103static bool dotrace_user = true;
104TUNABLE_BOOL("kern.boottrace.dotrace_user", &dotrace_user);
105
106static int sysctl_log(SYSCTL_HANDLER_ARGS);
107static int sysctl_boottrace(SYSCTL_HANDLER_ARGS);
108static int sysctl_runtrace(SYSCTL_HANDLER_ARGS);
109static int sysctl_shuttrace(SYSCTL_HANDLER_ARGS);
110static int sysctl_boottrace_reset(SYSCTL_HANDLER_ARGS);
111
112SYSCTL_NODE(_kern, OID_AUTO, boottrace, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
113 "boottrace statistics");
114
115SYSCTL_PROC(_kern_boottrace, OID_AUTO, log,
116 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_SKIP,
117 0, 0, sysctl_log, "A",
118 "Print a log of the boottrace trace data");
119SYSCTL_PROC(_kern_boottrace, OID_AUTO, boottrace,
120 CTLTYPE_STRING | CTLFLAG_WR | CTLFLAG_MPSAFE,
121 0, 0, sysctl_boottrace, "A",
122 "Capture a boot-time trace event");
123SYSCTL_PROC(_kern_boottrace, OID_AUTO, runtrace,
124 CTLTYPE_STRING | CTLFLAG_WR | CTLFLAG_MPSAFE,
125 0, 0, sysctl_runtrace, "A",
126 "Capture a run-time trace event");
127SYSCTL_PROC(_kern_boottrace, OID_AUTO, shuttrace,
128 CTLTYPE_STRING | CTLFLAG_WR | CTLFLAG_MPSAFE,
129 0, 0, sysctl_shuttrace, "A",
130 "Capture a shutdown-time trace event");
131SYSCTL_PROC(_kern_boottrace, OID_AUTO, reset,
132 CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_MPSAFE,
133 0, 0, sysctl_boottrace_reset, "A",
134 "Reset run-time tracing table");
135
136/*
137 * Global enable.
138 */
140SYSCTL_BOOL(_kern_boottrace, OID_AUTO, enabled, CTLFLAG_RDTUN,
142 "Boot-time and shutdown-time tracing enabled");
143
144/*
145 * Enable dumping of the shutdown trace entries to console.
146 */
147bool shutdown_trace = false;
148SYSCTL_BOOL(_kern_boottrace, OID_AUTO, shutdown_trace, CTLFLAG_RWTUN,
149 &shutdown_trace, 0,
150 "Enable kernel shutdown tracing to the console");
151
152/*
153 * Set the delta threshold (ms) below which events are ignored, used in
154 * determining what to dump to the console.
155 */
157SYSCTL_INT(_kern_boottrace, OID_AUTO, shutdown_trace_threshold, CTLFLAG_RWTUN,
159 "Tracing threshold (ms) below which tracing is ignored");
160
161/*
162 * Dump a trace to buffer or if buffer is NULL to console.
163 *
164 * Non-zero delta_threshold selectively prints entries based on delta
165 * with current and previous entry. Otherwise, delta_threshold of 0
166 * prints every trace entry and delta.
167 *
168 * Output something like this:
169 *
170 * CPU msecs delta process event
171 * 11 1228262715 0 init shutdown pre sync begin
172 * 3 1228265622 2907 init shutdown pre sync complete
173 * 3 1228265623 0 init shutdown turned swap off
174 * 18 1228266466 843 init shutdown unmounted all filesystems
175 *
176 * How to interpret:
177 *
178 * delta column represents the time in milliseconds between this event and the previous.
179 * Usually that means you can take the previous event, current event, match them
180 * up in the code, and whatever lies between is the culprit taking time.
181 *
182 * For example, above: Pre-Sync is taking 2907ms, and something between swap and unmount
183 * filesystems is taking 843 milliseconds.
184 *
185 * An event with a delta of 0 are 'landmark' events that simply exist in the output
186 * for the developer to know where the time measurement begins. The 0 is an arbitrary
187 * number that can effectively be ignored.
188 */
189#define BTC_DELTA_PRINT(bte, msecs, delta) do { \
190 if (sbp) { \
191 sbuf_printf(sbp, fmt, (bte)->cpuid, msecs, delta, \
192 (bte)->tdname, (bte)->name, (bte)->pid, \
193 (bte)->cputime / 1000000, \
194 ((bte)->cputime % 1000000) / 10000, \
195 (bte)->inblock, (bte)->oublock); \
196 } else { \
197 printf(fmt, (bte)->cpuid, msecs, delta, \
198 (bte)->tdname, (bte)->name, (bte)->pid, \
199 (bte)->cputime / 1000000, \
200 ((bte)->cputime % 1000000) / 10000, \
201 (bte)->inblock, (bte)->oublock); \
202 } \
203} while (0)
204
205/*
206 * Print the trace entries to the message buffer, or to an sbuf, if provided.
207 *
208 * Entries with a difference less than dthres will not be printed.
209 */
210static void
211boottrace_display(struct sbuf *sbp, struct bt_table *btp, uint64_t dthres)
212{
213 struct bt_event *evtp;
214 struct bt_event *last_evtp;
215 uint64_t msecs;
216 uint64_t first_msecs;
217 uint64_t last_msecs;
218 uint64_t dmsecs;
219 uint64_t last_dmsecs;
220 uint64_t total_dmsecs;
221 uint32_t i;
222 uint32_t curr;
223 const char *fmt = "%3u %10llu %10llu %-24s %-40s %5d %4d.%02d %5u %5u\n";
224 const char *hdr_fmt = "\n\n%3s %10s %10s %-24s %-40s %5s %6s %5s %5s\n";
225 bool printed;
226 bool last_printed;
227
228 /* Print the header */
229 if (sbp != NULL)
230 sbuf_printf(sbp, hdr_fmt,
231 "CPU", "msecs", "delta", "process",
232 "event", "PID", "CPUtime", "IBlks", "OBlks");
233 else
234 printf(hdr_fmt,
235 "CPU", "msecs", "delta", "process",
236 "event", "PID", "CPUtime", "IBlks", "OBlks");
237
238 first_msecs = 0;
239 last_evtp = NULL;
240 last_msecs = 0;
241 last_dmsecs = 0;
242 last_printed = false;
243 i = curr = btp->curr;
244
245 do {
246 evtp = &btp->table[i];
247 if (evtp->tsc == 0)
248 goto next;
249
250 msecs = cputick2usec(evtp->tick) / 1000;
251 dmsecs = (last_msecs != 0 && msecs > last_msecs) ?
252 msecs - last_msecs : 0;
253 printed = false;
254
255 /*
256 * If a threshold is defined, start filtering events by the
257 * delta of msecs.
258 */
259 if (dthres != 0 && (dmsecs > dthres)) {
260 /*
261 * Print the previous entry as a landmark, even if it
262 * falls below the threshold.
263 */
264 if (last_evtp != NULL && !last_printed)
265 BTC_DELTA_PRINT(last_evtp, last_msecs,
266 last_dmsecs);
267 BTC_DELTA_PRINT(evtp, msecs, dmsecs);
268 printed = true;
269 } else if (dthres == 0) {
270 BTC_DELTA_PRINT(evtp, msecs, dmsecs);
271 printed = true;
272 }
273 if (first_msecs == 0 || msecs < first_msecs)
274 first_msecs = msecs;
275 last_evtp = evtp;
276 last_msecs = msecs;
277 last_dmsecs = dmsecs;
278 last_printed = printed;
279 maybe_yield();
280next:
281 i = (i + 1) % btp->size;
282 } while (i != curr);
283
284 total_dmsecs = last_msecs > first_msecs ?
285 (last_msecs - first_msecs) : 0;
286 if (sbp != NULL)
287 sbuf_printf(sbp, "Total measured time: %ju msecs\n",
288 (uintmax_t)total_dmsecs);
289 else
290 printf("Total measured time: %ju msecs\n",
291 (uintmax_t)total_dmsecs);
292}
293
294/*
295 * Dump trace table entries to the console, given a delta threshold.
296 */
297void
299{
301 return;
302
303 if (shutdown || rebooting || KERNEL_PANICKED()) {
305 } else {
306 boottrace_display(NULL, &bt, 0);
307 boottrace_display(NULL, &rt, 0);
308 }
309}
310
311/*
312 * Records a new tracing event to the specified table.
313 *
314 * We don't use a lock because we want this to be callable from interrupt
315 * context.
316 */
317static int
318dotrace(struct bt_table *btp, const char *eventname, const char *tdname)
319{
320 uint32_t idx, nxt;
321 struct rusage usage;
322
323 MPASS(boottrace_enabled);
324 if (tdname == NULL)
325 tdname = (curproc->p_flag & P_SYSTEM) ?
326 curthread->td_name : curproc->p_comm;
327
328 dprintf("dotrace[");
329 dprintf("cpu=%u, pid=%d, tsc=%ju, tick=%d, td='%s', event='%s'",
330 PCPU_GET(cpuid), curthread->td_proc->p_pid,
331 (uintmax_t)get_cyclecount(), ticks, tdname, eventname);
332 if (btp->table == NULL) {
333 btp->drops_early++;
334 dprintf(", return=ENOSPC_1]\n");
335 return (ENOSPC);
336 }
337
338 /* Claim a slot in the table. */
339 do {
340 idx = btp->curr;
341 nxt = (idx + 1) % btp->size;
342 if (nxt == 0 && btp->wrap == 0) {
343 btp->drops_full++;
344 dprintf(", return=ENOSPC_2]\n");
345 return (ENOSPC);
346 }
347 } while (!atomic_cmpset_int(&btp->curr, idx, nxt));
348
349 btp->table[idx].cpuid = PCPU_GET(cpuid);
350 btp->table[idx].tsc = get_cyclecount(),
351 btp->table[idx].tick = cpu_ticks();
352 btp->table[idx].pid = curthread->td_proc->p_pid;
353
354 /*
355 * Get the resource usage for the process. Don't attempt this for the
356 * kernel proc0 or for critical section activities.
357 */
358 if ((curthread->td_proc == &proc0) || (curthread->td_critnest != 0)) {
359 btp->table[idx].cputime = 0;
360 btp->table[idx].inblock = 0;
361 btp->table[idx].oublock = 0;
362 } else {
363 kern_getrusage(curthread, RUSAGE_CHILDREN, &usage);
364 btp->table[idx].cputime =
365 (uint64_t)(usage.ru_utime.tv_sec * 1000000 +
366 usage.ru_utime.tv_usec + usage.ru_stime.tv_sec * 1000000 +
367 usage.ru_stime.tv_usec);
368 btp->table[idx].inblock = (uint32_t)usage.ru_inblock;
369 btp->table[idx].oublock = (uint32_t)usage.ru_oublock;
370 }
371 strlcpy(btp->table[idx].name, eventname, BT_EVENT_NAMELEN);
372 strlcpy(btp->table[idx].tdname, tdname, BT_EVENT_TDNAMELEN);
373
374 dprintf(", return=0]\n");
375 return (0);
376}
377
378/*
379 * Log various boot-time events, with the trace message encoded using
380 * printf-like arguments.
381 */
382int
383boottrace(const char *tdname, const char *fmt, ...)
384{
385 char eventname[BT_EVENT_NAMELEN];
386 struct bt_table *btp;
387 va_list ap;
388
389 if (!dotrace_kernel)
390 return (ENXIO);
391
392 va_start(ap, fmt);
393 vsnprintf(eventname, sizeof(eventname), fmt, ap);
394 va_end(ap);
395
396 btp = &bt;
397 if (bootdone)
398 btp = &rt;
399 if (shutdown || rebooting || KERNEL_PANICKED())
400 btp = &st;
401
402 return (dotrace(btp, eventname, tdname));
403}
404
405/*
406 * Log a run-time event & switch over to run-time tracing mode.
407 */
408static int
409runtrace(const char *eventname, const char *tdname)
410{
411
412 bootdone = true;
413 return (dotrace(&rt, eventname, tdname));
414}
415
416/*
417 * Parse a boottrace message from userspace.
418 *
419 * The input from may contain a ':' to denote tdname. If not, tdname is
420 * inferred from the process' name.
421 *
422 * e.g. reboot(8):SIGINT to init(8)
423 */
424static void
425boottrace_parse_message(char *message, char **eventname, char **tdname)
426{
427 char *delim;
428
429 delim = strchr(message, ':');
430 if (delim != NULL) {
431 *delim = '\0';
432 *tdname = message;
433 *eventname = ++delim;
434 } else {
435 *tdname = curproc->p_comm;
436 *eventname = message;
437 }
438}
439
440static int
441_boottrace_sysctl(struct bt_table *btp, struct sysctl_oid *oidp,
442 struct sysctl_req *req)
443{
444 char message[BT_MSGLEN];
445 char *eventname, *tdname;
446 int error;
447
448 if (!dotrace_user)
449 return (ENXIO);
450
451 message[0] = '\0';
452 error = sysctl_handle_string(oidp, message, sizeof(message), req);
453 if (error)
454 return (error);
455
456 boottrace_parse_message(message, &eventname, &tdname);
457 error = dotrace(btp, eventname, tdname);
458 if (error == ENOSPC) {
459 /* Ignore table full error. */
460 error = 0;
461 }
462 return (error);
463}
464
465static int
466sysctl_log(SYSCTL_HANDLER_ARGS)
467{
468 struct sbuf *sbuf;
469 int error;
470
471 if (!boottrace_enabled || req->newptr != NULL)
472 return (0);
473
474 sbuf = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
475 boottrace_display(sbuf, &bt, 0);
476 boottrace_display(sbuf, &rt, 0);
477 sbuf_finish(sbuf);
478 error = SYSCTL_OUT(req, sbuf_data(sbuf), sbuf_len(sbuf));
479 sbuf_delete(sbuf);
480
481 return (error);
482}
483
484static int
485sysctl_boottrace(SYSCTL_HANDLER_ARGS)
486{
487
489 return (0);
490
491 /* No output */
492 if (req->newptr == NULL)
493 return (0);
494
495 /* Trace to rt if we have reached multi-user. */
496 return (_boottrace_sysctl(bootdone ? &rt : &bt, oidp, req));
497}
498
499/*
500 * Log a run-time event and switch over to run-time tracing mode.
501 */
502static int
503sysctl_runtrace(SYSCTL_HANDLER_ARGS)
504{
505
507 return (0);
508
509 /* No output */
510 if (req->newptr == NULL)
511 return (0);
512
513 bootdone = true;
514 return (_boottrace_sysctl(&rt, oidp, req));
515}
516
517/*
518 * Log a shutdown-time event and switch over to shutdown tracing mode.
519 */
520static int
521sysctl_shuttrace(SYSCTL_HANDLER_ARGS)
522{
523
525 return (0);
526
527 /* No output */
528 if (req->newptr == NULL)
529 return (0);
530
531 shutdown = true;
532 return (_boottrace_sysctl(&st, oidp, req));
533}
534
535/*
536 * Reset the runtime tracing buffer.
537 */
538void
539boottrace_reset(const char *actor)
540{
541 char tmpbuf[64];
542
543 snprintf(tmpbuf, sizeof(tmpbuf), "reset: %s", actor);
544 runtrace(tmpbuf, NULL);
545}
546
547/*
548 * Note that a resize implies a reset, i.e., the index is reset to 0.
549 * We never shrink the array; we can only increase its size.
550 */
551int
552boottrace_resize(u_int newsize)
553{
554
555 if (newsize <= rt.size) {
556 return (EINVAL);
557 }
558 rt.table = realloc(rt.table, newsize * sizeof(struct bt_event),
559 M_BOOTTRACE, M_WAITOK | M_ZERO);
560 if (rt.table == NULL)
561 return (ENOMEM);
562
563 rt.size = newsize;
564 boottrace_reset("boottrace_resize");
565 return (0);
566}
567
568static int
569sysctl_boottrace_reset(SYSCTL_HANDLER_ARGS)
570{
571
573 return (0);
574
575 if (req->newptr != NULL)
576 boottrace_reset("sysctl_boottrace_reset");
577
578 return (0);
579}
580
581static void
583{
584
586 return;
587
588 /* Boottime trace table */
590 TUNABLE_INT_FETCH("kern.boottrace.table_size", &bt.size);
592 bt.table = malloc(bt.size * sizeof(struct bt_event), M_BOOTTRACE,
593 M_WAITOK | M_ZERO);
594
595 /* Stick in an initial entry. */
596 bt.table[0].cpuid = PCPU_GET(cpuid);
597 strlcpy(bt.table[0].tdname, "boottime", BT_EVENT_TDNAMELEN);
598 strlcpy(bt.table[0].name, "initial event", BT_EVENT_NAMELEN);
599 bt.curr = 1;
600
601 /* Run-time trace table (may wrap-around). */
602 rt.wrap = 1;
604 rt.table = malloc(rt.size * sizeof(struct bt_event), M_BOOTTRACE,
605 M_WAITOK | M_ZERO);
606
607 /* Shutdown trace table */
609 st.table = malloc(st.size * sizeof(struct bt_event), M_BOOTTRACE,
610 M_WAITOK | M_ZERO);
611}
612SYSINIT(boottrace, SI_SUB_CPU, SI_ORDER_ANY, boottrace_init, 0);
struct proc proc0
Definition: init_main.c:109
void boottrace_dump_console(void)
#define BTC_DELTA_PRINT(bte, msecs, delta)
static bool shutdown
static void boottrace_init(void)
#define dprintf(fmt,...)
static int shutdown_trace_threshold
static bool dotrace_user
bool __read_mostly boottrace_enabled
static int _boottrace_sysctl(struct bt_table *btp, struct sysctl_oid *oidp, struct sysctl_req *req)
static bool dotrace_kernel
static void boottrace_parse_message(char *message, char **eventname, char **tdname)
static int sysctl_boottrace_reset(SYSCTL_HANDLER_ARGS)
#define BT_TABLE_SHTSIZE
void boottrace_reset(const char *actor)
static int sysctl_runtrace(SYSCTL_HANDLER_ARGS)
static struct bt_table bt
#define BT_TABLE_DEFSIZE
SYSCTL_BOOL(_kern_boottrace, OID_AUTO, enabled, CTLFLAG_RDTUN, &boottrace_enabled, 0, "Boot-time and shutdown-time tracing enabled")
static int dotrace(struct bt_table *btp, const char *eventname, const char *tdname)
static void boottrace_display(struct sbuf *sbp, struct bt_table *btp, uint64_t dthres)
static int sysctl_boottrace(SYSCTL_HANDLER_ARGS)
int boottrace_resize(u_int newsize)
static bool bootdone
SYSCTL_NODE(_kern, OID_AUTO, boottrace, CTLFLAG_RD|CTLFLAG_MPSAFE, 0, "boottrace statistics")
bool shutdown_trace
static int sysctl_log(SYSCTL_HANDLER_ARGS)
SYSCTL_INT(_kern_boottrace, OID_AUTO, shutdown_trace_threshold, CTLFLAG_RWTUN, &shutdown_trace_threshold, 0, "Tracing threshold (ms) below which tracing is ignored")
static int sysctl_shuttrace(SYSCTL_HANDLER_ARGS)
static struct bt_table st
static MALLOC_DEFINE(M_BOOTTRACE, "boottrace", "memory for boot tracing")
#define BT_TABLE_RUNSIZE
int boottrace(const char *tdname, const char *fmt,...)
TUNABLE_BOOL("debug.boottrace.dotrace_debugging", &dotrace_debugging)
static struct bt_table rt
SYSINIT(boottrace, SI_SUB_CPU, SI_ORDER_ANY, boottrace_init, 0)
static int runtrace(const char *eventname, const char *tdname)
SYSCTL_PROC(_kern_boottrace, OID_AUTO, log, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_SKIP, 0, 0, sysctl_log, "A", "Print a log of the boottrace trace data")
static bool dotrace_debugging
#define BT_TABLE_MINSIZE
volatile int ticks
Definition: kern_clock.c:380
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
Definition: kern_malloc.c:632
void * realloc(void *addr, size_t size, struct malloc_type *mtp, int flags)
Definition: kern_malloc.c:987
int kern_getrusage(struct thread *td, int who, struct rusage *rup)
int rebooting
void maybe_yield(void)
Definition: kern_synch.c:652
int sysctl_handle_string(SYSCTL_HANDLER_ARGS)
Definition: kern_sysctl.c:1778
cpu_tick_f * cpu_ticks
Definition: kern_tc.c:2174
uint64_t cputick2usec(uint64_t tick)
Definition: kern_tc.c:2163
uint64_t tick
uint64_t cputime
uint32_t cpuid
uint32_t oublock
uint32_t inblock
char name[BT_EVENT_NAMELEN]
char tdname[BT_EVENT_TDNAMELEN]
uint64_t tsc
struct bt_event * table
uint32_t drops_full
uint32_t curr
uint32_t drops_early
uint32_t wrap
uint32_t size
static bool kasan_enabled __read_mostly
Definition: subr_asan.c:95
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
Definition: subr_prf.c:565
int printf(const char *fmt,...)
Definition: subr_prf.c:397
int snprintf(char *str, size_t size, const char *format,...)
Definition: subr_prf.c:550
void log(int level, const char *fmt,...)
Definition: subr_prf.c:314
int sbuf_finish(struct sbuf *s)
Definition: subr_sbuf.c:833
void sbuf_delete(struct sbuf *s)
Definition: subr_sbuf.c:898
int sbuf_printf(struct sbuf *s, const char *fmt,...)
Definition: subr_sbuf.c:739
ssize_t sbuf_len(struct sbuf *s)
Definition: subr_sbuf.c:877
char * sbuf_data(struct sbuf *s)
Definition: subr_sbuf.c:862
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
Definition: subr_sbuf.c:196