본문 바로가기

Core BSP 분석/리눅스 커널 핵심 분석

[리눅스커널] tracing: 부팅 과정에서 자동으로 ftrace 활성화하기

<커널: v5.10>
 
부팅 과정에서 ftrace가 초기화되면서 ftrace 로깅이 드라이버 레벨로 활성화가 되면,
구지 다음과 같은 명령어를 입력할 필요성을 못 느낍니다.
 
'echo 1 > /sys/kernel/debug/tracing/tracing_on'
 
본 페이지에 소개된 패치를 적용하면 부팅 과정에서 ftracing 로깅을 실행할 수 있습니다.
 
commit 7f75bdc9ac6a2bae4d6352d15640b331d9becfbb
Author: Austin Kim <austindh.kim@gmail.com>
Date:   Mon Sep 20 14:23:17 2021 +0900
 
    tracing: enable ftrace at boot
 
    Using 'echo 1 > /sys/kernel/debug/tracing/tracing_on',
    the ftrace is enabled. But sometimes we are in the situation where
    boot time should be measured using ftrace.
 
    With CONFIG_ENABLE_FTRACE_AT_BOOT enabled, the ftrace is enabled at boot.
 
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
old mode 100644
new mode 100755
index 29db703f6..9e02f297f
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -243,6 +243,13 @@ config STACK_TRACER
 
          Say N if unsure.
 
+config ENABLE_FTRACE_AT_BOOT
+       bool "Enable ftrace at boot"
+       depends on TRACING
+       default y
+    help
+               Enable ftrace at boot
+
 config TRACE_PREEMPT_TOGGLE
        bool
        help
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
old mode 100644
new mode 100755
index ab3cb67b8..e50fd2a8c
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -3424,6 +3424,47 @@ static __init int event_trace_enable(void)
        return 0;
 }
 
+#ifdef CONFIG_ENABLE_FTRACE_AT_BOOT
+static void ftrace_events_enable(int enable)
+{
+       if (enable) {
+               trace_set_clr_event(NULL, "printk", 1);
+               trace_set_clr_event(NULL, "console", 1);
+               trace_set_clr_event(NULL, "signal_generate", 1);
+               trace_set_clr_event(NULL, "signal_deliver", 1);
+    } else {
+               tracing_off();
+               trace_set_clr_event(NULL, NULL, 0);
+    }
+}
+
+static __init int enable_ftrace_boot(void)
+{
+       struct trace_array *tr;
+       int ret = 0;
+
+       tr = top_trace_array();
+       if (!tr) {
+               pr_err("%s: Invalid tr from top_trace_array n", __func__);
+               return -ENODEV;
+       }
+
+       ret = tracing_update_buffers();
+       if (ret != 0) {
+               pr_err("%s: invalid buffer ret=%dn", __func__, ret);
+               return -ENODEV;
+       }
+
+       ftrace_events_enable(1);
+       set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 0);
+
+       tracing_on();
+
+       return 0;
+}
+late_initcall(enable_ftrace_boot);
+#endif
+
 /*
  * event_trace_enable() is called from trace_event_init() first to
  * initialize events and perhaps start any events that are on the