// SPDX-License-Identifier: GPL-2.0 #include <linux/delay.h> #include <linux/module.h> #include <linux/kthread.h> #include <linux/trace_clock.h> #define CREATE_TRACE_POINTS #include "trace_benchmark.h" static struct task_struct *bm_event_thread; static char bm_str[BENCHMARK_EVENT_STRLEN] = …; static u64 bm_total; static u64 bm_totalsq; static u64 bm_last; static u64 bm_max; static u64 bm_min; static u64 bm_first; static u64 bm_cnt; static u64 bm_stddev; static unsigned int bm_avg; static unsigned int bm_std; static bool ok_to_run; /* * This gets called in a loop recording the time it took to write * the tracepoint. What it writes is the time statistics of the last * tracepoint write. As there is nothing to write the first time * it simply writes "START". As the first write is cold cache and * the rest is hot, we save off that time in bm_first and it is * reported as "first", which is shown in the second write to the * tracepoint. The "first" field is written within the statics from * then on but never changes. */ static void trace_do_benchmark(void) { … } static int benchmark_event_kthread(void *arg) { … } /* * When the benchmark tracepoint is enabled, it calls this * function and the thread that calls the tracepoint is created. */ int trace_benchmark_reg(void) { … } /* * When the benchmark tracepoint is disabled, it calls this * function and the thread that calls the tracepoint is deleted * and all the numbers are reset. */ void trace_benchmark_unreg(void) { … } static __init int ok_to_run_trace_benchmark(void) { … } early_initcall(ok_to_run_trace_benchmark);