forked from Imagelibrary/seL4
Compare commits
4 Commits
misra-12.1
...
df-public
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35e91f397e | ||
|
|
4d43070612 | ||
|
|
86b02ba104 | ||
|
|
cc41ba5d52 |
@@ -18,6 +18,10 @@
|
||||
#define PMCR_ECNT_RESET 1
|
||||
#define PMCR_CCNT_RESET 2
|
||||
|
||||
#if defined(CONFIG_BENCHMARK_TRACK_UTILISATION) && defined(KERNEL_PMU_IRQ)
|
||||
#define CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT 1
|
||||
#endif
|
||||
|
||||
void arm_init_ccnt(void);
|
||||
|
||||
static inline timestamp_t timestamp(void)
|
||||
@@ -28,22 +32,22 @@ static inline timestamp_t timestamp(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
|
||||
extern bool_t benchmark_log_utilisation_enabled;
|
||||
extern uint64_t ccnt_num_overflows;
|
||||
static inline void handleOverflowIRQ(void)
|
||||
{
|
||||
if (likely(benchmark_log_utilisation_enabled)) {
|
||||
if (likely(NODE_STATE(benchmark_log_utilisation_enabled))) {
|
||||
NODE_STATE(ksCurThread)->benchmark.utilisation += UINT32_MAX - NODE_STATE(ksCurThread)->benchmark.schedule_start_time;
|
||||
NODE_STATE(ksCurThread)->benchmark.schedule_start_time = 0;
|
||||
ccnt_num_overflows++;
|
||||
NODE_STATE(ccnt_num_overflows)++;
|
||||
}
|
||||
armv_handleOverflowIRQ();
|
||||
}
|
||||
#endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
|
||||
|
||||
static inline void benchmark_arch_utilisation_reset(void)
|
||||
{
|
||||
ccnt_num_overflows = 0;
|
||||
}
|
||||
#ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
|
||||
NODE_STATE(ccnt_num_overflows) = 0;
|
||||
#endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
|
||||
}
|
||||
#endif /* CONFIG_ENABLE_BENCHMARKS */
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ NODE_STATE_DECLARE(bool_t, armHSVCPUActive);
|
||||
NODE_STATE_DECLARE(bool_t, armHSFPUEnabled);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(CONFIG_BENCHMARK_TRACK_UTILISATION) && defined(KERNEL_PMU_IRQ)
|
||||
NODE_STATE_DECLARE(uint64_t, ccnt_num_overflows);
|
||||
#endif /* defined(CONFIG_BENCHMARK_TRACK_UTILISATION) && defined(KERNEL_PMU_IRQ) */
|
||||
NODE_STATE_END(archNodeState);
|
||||
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
|
||||
@@ -13,10 +13,7 @@
|
||||
#include <model/statedata.h>
|
||||
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
extern bool_t benchmark_log_utilisation_enabled;
|
||||
extern timestamp_t ksEnter;
|
||||
extern timestamp_t benchmark_start_time;
|
||||
extern timestamp_t benchmark_end_time;
|
||||
|
||||
void benchmark_track_utilisation_dump(void);
|
||||
|
||||
@@ -27,7 +24,7 @@ void benchmark_track_reset_utilisation(void);
|
||||
static inline void benchmark_utilisation_switch(tcb_t *heir, tcb_t *next)
|
||||
{
|
||||
/* Add heir thread utilisation */
|
||||
if (likely(benchmark_log_utilisation_enabled)) {
|
||||
if (likely(NODE_STATE(benchmark_log_utilisation_enabled))) {
|
||||
|
||||
/* Check if an overflow occurred while we have been in the kernel */
|
||||
if (likely(ksEnter > heir->benchmark.schedule_start_time)) {
|
||||
@@ -55,8 +52,8 @@ static inline void benchmark_utilisation_finalise(void)
|
||||
/* Add the time between when NODE_STATE(ksCurThread), and benchmark finalise */
|
||||
benchmark_utilisation_switch(NODE_STATE(ksCurThread), NODE_STATE(ksIdleThread));
|
||||
|
||||
benchmark_end_time = ksEnter;
|
||||
benchmark_log_utilisation_enabled = false;
|
||||
NODE_STATE(benchmark_end_time) = ksEnter;
|
||||
NODE_STATE(benchmark_log_utilisation_enabled) = false;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
|
||||
@@ -31,6 +31,13 @@ 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(benchmark_log_utilisation_enabled)) {
|
||||
timestamp_t exit = timestamp();
|
||||
benchmark_kernel_time += exit - ksEnter;
|
||||
}
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
|
||||
arch_c_exit_hook();
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,12 @@ NODE_STATE_DECLARE(word_t, ksFPURestoresSinceSwitch);
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
NODE_STATE_DECLARE(tcb_t *, ksDebugTCBs);
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
NODE_STATE_DECLARE(bool_t, benchmark_log_utilisation_enabled);
|
||||
NODE_STATE_DECLARE(timestamp_t, benchmark_start_time);
|
||||
NODE_STATE_DECLARE(timestamp_t, benchmark_end_time);
|
||||
NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_time);
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
|
||||
NODE_STATE_END(nodeState);
|
||||
|
||||
|
||||
@@ -748,7 +748,32 @@ LIBSEL4_INLINE_FUNC void seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr
|
||||
arm_sys_send_recv(seL4_SysBenchmarkResetThreadUtilisation, tcb_cptr, &unused0, 0, &unused1, &unused2, &unused3,
|
||||
&unused4, &unused5, 0);
|
||||
}
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
LIBSEL4_INLINE_FUNC void seL4_BenchmarkDumpAllThreadsUtilisation(void)
|
||||
{
|
||||
seL4_Word unused0 = 0;
|
||||
seL4_Word unused1 = 0;
|
||||
seL4_Word unused2 = 0;
|
||||
seL4_Word unused3 = 0;
|
||||
seL4_Word unused4 = 0;
|
||||
seL4_Word unused5 = 0;
|
||||
|
||||
arm_sys_send_recv(seL4_SysBenchmarkDumpAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, &unused3, &unused4, &unused5, 0);
|
||||
}
|
||||
|
||||
LIBSEL4_INLINE_FUNC void seL4_BenchmarkResetAllThreadsUtilisation(void)
|
||||
{
|
||||
seL4_Word unused0 = 0;
|
||||
seL4_Word unused1 = 0;
|
||||
seL4_Word unused2 = 0;
|
||||
seL4_Word unused3 = 0;
|
||||
seL4_Word unused4 = 0;
|
||||
seL4_Word unused5 = 0;
|
||||
|
||||
arm_sys_send_recv(seL4_SysBenchmarkResetAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, &unused3, &unused4, &unused5, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
#endif /* CONFIG_ENABLE_BENCHMARKS */
|
||||
|
||||
|
||||
@@ -64,6 +64,10 @@
|
||||
<syscall name="BenchmarkGetThreadUtilisation" />
|
||||
<syscall name="BenchmarkResetThreadUtilisation" />
|
||||
</config>
|
||||
<config condition="defined CONFIG_DEBUG_BUILD && defined CONFIG_BENCHMARK_TRACK_UTILISATION">
|
||||
<syscall name="BenchmarkDumpAllThreadsUtilisation" />
|
||||
<syscall name="BenchmarkResetAllThreadsUtilisation" />
|
||||
</config>
|
||||
<config condition="defined CONFIG_KERNEL_X86_DANGEROUS_MSR">
|
||||
<syscall name="X86DangerousWRMSR"/>
|
||||
<syscall name="X86DangerousRDMSR"/>
|
||||
|
||||
@@ -15,7 +15,8 @@ enum benchmark_track_util_ipc_index {
|
||||
BENCHMARK_TCB_UTILISATION,
|
||||
BENCHMARK_IDLE_LOCALCPU_UTILISATION,
|
||||
BENCHMARK_IDLE_TCBCPU_UTILISATION,
|
||||
BENCHMARK_TOTAL_UTILISATION
|
||||
BENCHMARK_TOTAL_UTILISATION,
|
||||
BENCHMARK_KERNEL_UTILISATION
|
||||
};
|
||||
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
|
||||
@@ -282,6 +282,29 @@ seL4_BenchmarkGetThreadUtilisation(seL4_Word tcb_cptr);
|
||||
*/
|
||||
LIBSEL4_INLINE_FUNC void
|
||||
seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr);
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
/**
|
||||
* @xmlonly <manual name="Dump All Threads Utilisation" label="sel4_benchmarkdumpallthreadsutilisation"/> @endxmlonly
|
||||
* @brief Print the current accumulated cycle count for every thread on the current node.
|
||||
*
|
||||
* Uses kernel's printf to print number of cycles on each line in the following format: thread_name,thread_cycles
|
||||
*
|
||||
*/
|
||||
LIBSEL4_INLINE_FUNC void
|
||||
seL4_BenchmarkDumpAllThreadsUtilisation(void);
|
||||
|
||||
/**
|
||||
* @xmlonly <manual name="Reset All Threads Utilisation" label="sel4_benchmarkresetallthreadsutilisation"/> @endxmlonly
|
||||
* @brief Reset the accumulated cycle count for every thread on the current node.
|
||||
*
|
||||
* Reset the cycle count for each thread to 0.
|
||||
*
|
||||
*/
|
||||
LIBSEL4_INLINE_FUNC void
|
||||
seL4_BenchmarkResetAllThreadsUtilisation(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
@@ -981,6 +981,29 @@ LIBSEL4_INLINE_FUNC void seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr
|
||||
x86_sys_send_recv(seL4_SysBenchmarkResetThreadUtilisation, tcb_cptr, &unused0, 0, &unused1, &unused2, MCS_COND(0,
|
||||
&unused3));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
LIBSEL4_INLINE_FUNC void seL4_BenchmarkDumpAllThreadsUtilisation(void)
|
||||
{
|
||||
seL4_Word unused0 = 0;
|
||||
seL4_Word unused1 = 0;
|
||||
seL4_Word unused2 = 0;
|
||||
LIBSEL4_UNUSED seL4_Word unused3 = 0;
|
||||
|
||||
x86_sys_send_recv(seL4_SysBenchmarkDumpAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3));
|
||||
}
|
||||
|
||||
LIBSEL4_INLINE_FUNC seL4_Word seL4_BenchmarkResetAllThreadsUtilisation(void)
|
||||
{
|
||||
seL4_Word unused0 = 0;
|
||||
seL4_Word unused1 = 0;
|
||||
seL4_Word unused2 = 0;
|
||||
LIBSEL4_UNUSED seL4_Word unused3 = 0;
|
||||
|
||||
x86_sys_send_recv(seL4_SysBenchmarkResetAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
#endif /* CONFIG_ENABLE_BENCHMARKS */
|
||||
|
||||
|
||||
@@ -764,6 +764,33 @@ LIBSEL4_INLINE_FUNC void seL4_BenchmarkResetThreadUtilisation(seL4_Word tcb_cptr
|
||||
x64_sys_send_recv(seL4_SysBenchmarkResetThreadUtilisation, tcb_cptr, &unused0, 0, &unused1, &unused2, &unused3,
|
||||
&unused4, &unused5, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
LIBSEL4_INLINE_FUNC void seL4_BenchmarkDumpAllThreadsUtilisation(void)
|
||||
{
|
||||
seL4_Word unused0 = 0;
|
||||
seL4_Word unused1 = 0;
|
||||
seL4_Word unused2 = 0;
|
||||
seL4_Word unused3 = 0;
|
||||
seL4_Word unused4 = 0;
|
||||
seL4_Word unused5 = 0;
|
||||
|
||||
x64_sys_send_recv(seL4_SysBenchmarkDumpAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, &unused3, &unused4, &unused5, 0);
|
||||
}
|
||||
|
||||
LIBSEL4_INLINE_FUNC void seL4_BenchmarkResetAllThreadsUtilisation(void)
|
||||
{
|
||||
seL4_Word unused0 = 0;
|
||||
seL4_Word unused1 = 0;
|
||||
seL4_Word unused2 = 0;
|
||||
seL4_Word unused3 = 0;
|
||||
seL4_Word unused4 = 0;
|
||||
seL4_Word unused5 = 0;
|
||||
|
||||
x64_sys_send_recv(seL4_SysBenchmarkResetAllThreadsUtilisation, 0, &unused0, 0, &unused1, &unused2, &unused3, &unused4, &unused5, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
#endif /* CONFIG_ENABLE_BENCHMARKS */
|
||||
|
||||
|
||||
@@ -208,10 +208,11 @@ exception_t handleUnknownSyscall(word_t w)
|
||||
ksLogIndex = 0;
|
||||
#endif /* CONFIG_BENCHMARK_USE_KERNEL_LOG_BUFFER */
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
benchmark_log_utilisation_enabled = true;
|
||||
NODE_STATE(benchmark_log_utilisation_enabled) = true;
|
||||
NODE_STATE(ksIdleThread)->benchmark.utilisation = 0;
|
||||
NODE_STATE(ksCurThread)->benchmark.schedule_start_time = ksEnter;
|
||||
benchmark_start_time = ksEnter;
|
||||
NODE_STATE(benchmark_start_time) = ksEnter;
|
||||
NODE_STATE(benchmark_kernel_time) = 0;
|
||||
benchmark_arch_utilisation_reset();
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
setRegister(NODE_STATE(ksCurThread), capRegister, seL4_NoError);
|
||||
@@ -247,6 +248,19 @@ exception_t handleUnknownSyscall(word_t w)
|
||||
benchmark_track_reset_utilisation();
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
else if (w == SysBenchmarkDumpAllThreadsUtilisation) {
|
||||
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = curr->tcbDebugNext) {
|
||||
printf("%s,%ld\n", curr->tcbName, (word_t) curr->benchmark.utilisation);
|
||||
}
|
||||
return EXCEPTION_NONE;
|
||||
} else if (w == SysBenchmarkResetAllThreadsUtilisation) {
|
||||
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = curr->tcbDebugNext) {
|
||||
curr->benchmark.utilisation = 0;
|
||||
}
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
|
||||
else if (w == SysBenchmarkNullSyscall) {
|
||||
|
||||
@@ -16,7 +16,7 @@ seL4_Word ksLogIndexFinalized = 0;
|
||||
#endif /* CONFIG_MAX_NUM_TRACE_POINTS > 0 */
|
||||
|
||||
#ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
|
||||
uint64_t ccnt_num_overflows;
|
||||
UP_STATE_DEFINE(uint64_t, ccnt_num_overflows);
|
||||
#endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
|
||||
|
||||
#ifdef CONFIG_ENABLE_BENCHMARKS
|
||||
|
||||
@@ -194,14 +194,6 @@ if(KernelArchArmV6)
|
||||
set(KernelSetTLSBaseSelf ON)
|
||||
endif()
|
||||
|
||||
# TODO: this config has no business being in the build system, and should
|
||||
# be moved to C headers, but for now must be emulated here for compatibility
|
||||
if(KernelBenchmarksTrackUtilisation AND KernelArchARM)
|
||||
config_set(KernelArmEnablePMUOverflowInterrupt ARM_ENABLE_PMU_OVERFLOW_INTERRUPT ON)
|
||||
else()
|
||||
config_set(KernelArmEnablePMUOverflowInterrupt ARM_ENABLE_PMU_OVERFLOW_INTERRUPT OFF)
|
||||
endif()
|
||||
|
||||
# Provides a 4K region of read-only memory mapped into every vspace to
|
||||
# provide a virtual thread-id register not otherwise provided by the
|
||||
# platform.
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
|
||||
bool_t benchmark_log_utilisation_enabled;
|
||||
timestamp_t ksEnter;
|
||||
timestamp_t benchmark_start_time;
|
||||
timestamp_t benchmark_end_time;
|
||||
|
||||
void benchmark_track_utilisation_dump(void)
|
||||
{
|
||||
@@ -43,10 +40,11 @@ void benchmark_track_utilisation_dump(void)
|
||||
|
||||
#ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
|
||||
buffer[BENCHMARK_TOTAL_UTILISATION] =
|
||||
(ccnt_num_overflows * 0xFFFFFFFFU) + benchmark_end_time - benchmark_start_time;
|
||||
(NODE_STATE(ccnt_num_overflows) * 0xFFFFFFFFU) + NODE_STATE(benchmark_end_time) - NODE_STATE(benchmark_start_time);
|
||||
#else
|
||||
buffer[BENCHMARK_TOTAL_UTILISATION] = benchmark_end_time - benchmark_start_time; /* Overall time */
|
||||
buffer[BENCHMARK_TOTAL_UTILISATION] = NODE_STATE(benchmark_end_time) - NODE_STATE(benchmark_start_time); /* Overall time */
|
||||
#endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
|
||||
buffer[BENCHMARK_KERNEL_UTILISATION] = NODE_STATE(benchmark_kernel_time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ UP_STATE_DEFINE(sched_context_t *, ksCurSC);
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
UP_STATE_DEFINE(tcb_t *, ksDebugTCBs);
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
UP_STATE_DEFINE(bool_t, benchmark_log_utilisation_enabled);
|
||||
UP_STATE_DEFINE(timestamp_t, benchmark_start_time);
|
||||
UP_STATE_DEFINE(timestamp_t, benchmark_end_time);
|
||||
UP_STATE_DEFINE(timestamp_t, benchmark_kernel_time);
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
|
||||
|
||||
/* Units of work we have completed since the last time we checked for
|
||||
* pending interrupts */
|
||||
|
||||
Reference in New Issue
Block a user