diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c index 3202b9b..2c9c53f 100644 --- a/sys/kern/kern_ktr.c +++ b/sys/kern/kern_ktr.c @@ -98,6 +98,7 @@ static MALLOC_DEFINE(M_KTR, "KTR", "KTR"); FEATURE(ktr, "Kernel support for KTR kernel tracing facility"); volatile int ktr_idx = 0; +volatile int ktr_overflow = 0; /* Overflow detection during boot */ int ktr_mask = KTR_MASK; int ktr_compile = KTR_COMPILE; int ktr_entries = KTR_BOOT_ENTRIES; @@ -213,13 +214,19 @@ ktr_entries_initializer(void *dummy __unused) ktr_mask = 0; ktr_buf = malloc(sizeof(*ktr_buf) * KTR_ENTRIES, M_KTR, M_WAITOK | M_ZERO); - memcpy(ktr_buf, ktr_buf_init + ktr_idx, - (KTR_BOOT_ENTRIES - ktr_idx) * sizeof(*ktr_buf)); - if (ktr_idx != 0) - memcpy(ktr_buf + KTR_BOOT_ENTRIES - ktr_idx, ktr_buf_init, - ktr_idx * sizeof(*ktr_buf)); + if (ktr_overflow >= KTR_BOOT_ENTRIES) { + memcpy(ktr_buf, ktr_buf_init + ktr_idx, + (KTR_BOOT_ENTRIES - ktr_idx) * sizeof(*ktr_buf)); + if (ktr_idx != 0) + memcpy(ktr_buf + KTR_BOOT_ENTRIES - ktr_idx, + ktr_buf_init, ktr_idx * sizeof(*ktr_buf)); + } + else + memcpy(ktr_buf, ktr_buf_init, ktr_idx * sizeof(*ktr_buf)); ktr_entries = KTR_ENTRIES; ktr_mask = mask; + free(ktr_buf_init, M_KTR); + ktr_buf_init = NULL; } SYSINIT(ktr_entries_initializer, SI_SUB_KMEM, SI_ORDER_ANY, ktr_entries_initializer, NULL); @@ -380,6 +387,9 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format, saveindex = ktr_idx; newindex = (saveindex + 1) % ktr_entries; } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0); + /* This happens only in early boot */ + if (ktr_buf_init != NULL) + ktr_overflow++; entry = &ktr_buf[saveindex]; } entry->ktr_timestamp = KTR_TIME;