There's a few cases in the kernel where the ksKernelEntry tracking
is not perfect, such as in SError reporting, and (I believe) a few
other places which I haven't tracked down to a cause - but some of
e.g. the RISC-V trap code where the first entry faults and the 2nd
proceeds can report stale information.
In these cases, the kernel says that the entry was via a certain
syscall or interrupt (etc), even though that was clearly not the
case because we know the kernel exited. Now we will print out this:
halting...
Kernel entry via Unknown (0)
The changes:
- When exiting the kernel, via `c_exit_hook()`, reset
`ksKernelEntry.path` to "Unknown".
An alternative here would have been add a global "valid" boolean
to the kernel state, but this requires modifying every site where
we set the ksKernelEntry.path to also set valid = true, which is
ugly.
- Remove Entry_UnimplementedDevice from entry_type_t as it is never
used, to leave enough room to add Entry_Unknown.
- Switch out the CONFIG_DEBUG_BUILD || BENCHMARK TRACK ENTRIES #if
in the x86 breakpoint code with the more concise
`TRACK_KERNEL_ENTRIES` define used elsewhere.
Signed-off-by: julia <git.ts@trainwit.ch>
50 lines
1.5 KiB
C
50 lines
1.5 KiB
C
/*
|
|
* Copyright 2016, General Dynamics C4 Systems
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <config.h>
|
|
#include <util.h>
|
|
#include <arch/kernel/traps.h>
|
|
#include <smp/lock.h>
|
|
|
|
/* This C function should be the first thing called from C after entry from
|
|
* assembly. It provides a single place to do any entry work that is not
|
|
* done in assembly for various reasons */
|
|
static inline void c_entry_hook(void)
|
|
{
|
|
arch_c_entry_hook();
|
|
#if defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES) || defined(CONFIG_BENCHMARK_TRACK_UTILISATION)
|
|
ksEnter = timestamp();
|
|
#endif
|
|
}
|
|
|
|
/* This C function should be the last thing called from C before exiting
|
|
* the kernel (be it to assembly or returning to user space). It provides
|
|
* a place to provide any additional instrumentation or functionality
|
|
* in C before leaving the kernel */
|
|
static inline void c_exit_hook(void)
|
|
{
|
|
#ifdef CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES
|
|
benchmark_track_exit();
|
|
#endif /* CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES */
|
|
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
|
if (likely(NODE_STATE(benchmark_log_utilisation_enabled))) {
|
|
timestamp_t exit = timestamp();
|
|
NODE_STATE(ksCurThread)->benchmark.number_kernel_entries++;
|
|
NODE_STATE(ksCurThread)->benchmark.kernel_utilisation += exit - ksEnter;
|
|
NODE_STATE(benchmark_kernel_number_entries)++;
|
|
NODE_STATE(benchmark_kernel_time) += exit - ksEnter;
|
|
}
|
|
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
|
|
|
#ifdef TRACK_KERNEL_ENTRIES
|
|
ksKernelEntry.path = Entry_Unknown;
|
|
#endif
|
|
|
|
arch_c_exit_hook();
|
|
}
|
|
|