ftrace 활용 — function·function_graph·latency tracer
#한 줄 요약
“ftrace는 커널을 다시 컴파일하지 않고 모든 함수 진입과 이탈, 인터럽트 지연을 추적하는 빌트인 도구입니다.”
#어떤 문제를 푸는가
커널의 어느 함수에서 시간이 새는지, 인터럽트가 얼마나 오래 disable되는지, real-time task가 왜 wake-up이 늦었는지 같은 질문은 perf의 sampling만으로는 답하기 어렵습니다. Sampling은 통계적이며 짧은 spike를 놓칠 수 있기 때문입니다.
ftrace는 GCC의 -pg로 모든 커널 함수 앞뒤에 trace hook이 삽입된 상태에서, runtime에 그 hook을 켜고 끄는 방식입니다. 비활성 상태에서는 NOP 두 명령과 같아 거의 zero overhead이며, 활성화 시에만 측정 비용이 발생합니다.
이 글에서는 /sys/kernel/debug/tracing 인터페이스, function tracer, function_graph, latency tracer를 다루며, trace-cmd와 KernelShark도 짧게 살펴봅니다.
#tracefs 인터페이스
ftrace는 tracefs라는 가상 파일시스템으로 노출됩니다.
mount -t tracefs nodev /sys/kernel/tracingcd /sys/kernel/tracinglsavailable_tracers current_tracer traceavailable_events events trace_pipeset_event set_ftrace_filter set_graph_functiontracing_on tracing_max_latency기본 사용 패턴은 다음과 같습니다.
echo function > current_tracer # tracer 선택echo 1 > tracing_on # 시작sleep 1echo 0 > tracing_on # 정지cat trace # 결과 확인#Function Tracer — 모든 함수 진입 기록
cd /sys/kernel/tracingecho function > current_tracerecho 1 > tracing_onsleep 0.1echo 0 > tracing_onhead trace <idle>-0 [000] 1234.567: cpuidle_enter <-cpu_startup_entry <idle>-0 [000] 1234.567: cpuidle_enter_state <-cpuidle_enter <idle>-0 [000] 1234.568: arch_cpu_idle <-cpuidle_enter_state app-1234 [001] 1234.568: __schedule <-schedule app-1234 [001] 1234.568: pick_next_task <-__schedule너무 많은 함수가 찍히므로 필터를 거는 것이 필수입니다.
echo 'tcp_*' > set_ftrace_filter # 'tcp_'로 시작하는 함수만echo '!nf_*' >> set_ftrace_filter # 'nf_' 제외#Function Graph Tracer — 호출 그래프와 시간
echo function_graph > current_tracerecho do_sys_open > set_graph_functionecho 1 > tracing_oncat /etc/hostname > /dev/nullecho 0 > tracing_oncat trace 1) | do_sys_open() { 1) | getname() { 1) 0.234 us | kmem_cache_alloc(); 1) 1.456 us | } 1) | do_filp_open() { 1) | path_openat() { 1) 3.123 us | link_path_walk(); 1) 5.678 us | } 1) 8.901 us | } 1) + 12.345 us | }들여쓰기로 호출 깊이를, 우측의 us 값으로 함수 전체 실행 시간을 보여줍니다. +는 10us 이상, !는 100us 이상을 표시합니다.
#Latency Tracer — irqsoff·preemptoff·wakeup_rt
Real-time 시스템에서 가장 중요한 metric은 worst-case latency입니다. 평균은 좋아도 한 번의 100us spike가 deadline을 깨면 의미가 없습니다.
echo irqsoff > current_tracer # IRQ disable 구간 측정echo 0 > tracing_max_latency # 리셋echo 1 > tracing_onsleep 10cat trace# tracer: irqsoff# latency: 234 us, #20/20, CPU#1# -----------------# | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0)# -----------------# => started at: __do_softirq# => ended at: net_rx_action| Tracer | 측정 대상 |
|---|---|
irqsoff | 인터럽트가 disable된 가장 긴 구간 |
preemptoff | preemption이 disable된 가장 긴 구간 |
preemptirqsoff | 둘 다 disable된 구간 |
wakeup | 가장 우선순위 높은 task의 wake-up latency |
wakeup_rt | RT task만 대상 |
wakeup_dl | Deadline scheduler task |
wakeup_rt는 PREEMPT_RT 커널에서 hardware interrupt부터 RT task가 CPU를 받기까지의 시간을 측정합니다. 자동차나 산업 제어에서 핵심 지표입니다.
#Event Tracing — Tracepoint 직접 활성화
ftrace는 perf와 같은 tracepoint를 공유합니다.
echo 1 > events/sched/sched_switch/enableecho 1 > events/irq/irq_handler_entry/enableecho 1 > tracing_onsleep 1echo 0 > tracing_oncat trace또는 그룹 전체를 한 번에 켤 수 있습니다.
echo 1 > events/sched/enable # sched 그룹 전체echo 1 > events/enable # 모든 event (주의)특정 조건만 trace하려면 filter를 사용합니다.
echo 'prev_pid == 1234' > events/sched/sched_switch/filter#trace-cmd — Wrapper
직접 tracefs를 만지는 대신 trace-cmd가 편합니다.
trace-cmd record -p function_graph -l 'tcp_*' ./apptrace-cmd report # 사람이 보기 좋은 포맷trace-cmd report -O cpu # CPU별 정렬생성된 trace.dat은 KernelShark로 GUI 시각화도 가능합니다.
kernelshark trace.datCPU별 timeline, 프로세스 상태 색상, zoom in/out으로 마이크로초 단위 분석이 가능합니다.
#kprobe·uprobe로 동적 trace point 추가
미리 정의된 tracepoint가 없는 함수도 kprobe로 동적으로 hook을 걸 수 있습니다.
echo 'p:my_open do_sys_open filename=+0(%si):string' > kprobe_eventsecho 1 > events/kprobes/my_open/enablecat trace_pipe이는 ftrace의 정적 hook을 보완하며, 모듈 함수나 inline되지 않은 함수에 사용합니다. eBPF의 base가 같은 mechanism입니다.
#Overhead — Nop의 이점
ftrace의 가장 큰 장점은 비활성 상태의 거의 zero overhead입니다.
비활성 (nop): ~1-2% (NOP 명령 비용)function: ~10-30% (모든 함수 hook)function_graph: ~30-50%event tracing: 1-5% (event 빈도 의존)latency tracer: 5-15%Production에서 latency tracer는 background로 켜 두고, function tracer는 디버깅 세션에만 사용하는 것이 보통입니다.
#자주 보는 함정과 안티패턴
⚠️ Filter 없이 function tracer 활성화
echo function > current_tracerecho 1 > tracing_on# → 버퍼가 1초도 안 되어 가득 참set_ftrace_filter로 좁히지 않으면 ring buffer가 즉시 wrap-around합니다.
⚠️ tracing_max_latency 리셋을 잊음
echo irqsoff > current_tracer# → 어제의 latency가 그대로 표시됨새 측정 전에 echo 0 > tracing_max_latency로 리셋해야 합니다.
⚠️ ring buffer 크기 부족
echo 4096 > buffer_size_kb # 기본은 1408 KB긴 trace는 buffer를 늘려야 wrap이 발생하지 않습니다. CPU당 buffer 크기이므로 코어 수만큼 총 메모리가 잡힙니다.
⚠️ tracing_on을 끄지 않고 cat trace
cat trace # tracing 계속 중# → 읽는 동안에도 새 event가 쌓여 inconsistentstable한 snapshot이 필요하면 먼저 echo 0 > tracing_on을 실행합니다.
#정리
- ftrace는 GCC
-pghook을 runtime에 토글하는 방식으로 비활성 시 zero overhead입니다. functiontracer는 모든 진입을,function_graph는 호출 그래프와 시간을 보여줍니다.irqsoff,preemptoff,wakeup_rt로 worst-case latency를 측정합니다.- Tracepoint는 ftrace와 perf가 공유하는 정적 probe입니다.
trace-cmd와 KernelShark로 record와 GUI 시각화가 가능합니다.- Filter 없는 function tracer는 ring buffer를 즉시 wrap시키므로 좁은 범위 지정이 필수입니다.
다음 편은 eBPF/bpftrace — 안전한 커널 내 프로그램으로 분석합니다.
#관련 항목
Embedded Performance Engineering · 43 of 57
- 1 Embedded Performance Engineering — 임베디드 성능 엔지니어링 시리즈 소개
- 2 임베디드 성능 분석 방법론 — Measure → Analyze → Optimize 사이클
- 3 성능 지표 정의 — Latency·Throughput·Utilization 분석
- 4 성능 측정의 기본 — Wall-Clock·CPU Cycle·Instruction Count
- 5 성능 데이터 통계적 분석 — Percentile·Histogram·평균의 함정
- 6 실시간 성능 분석 — WCET·Jitter·Deadline Miss 측정
- 7 임베디드 벤치마킹 기초 — 재현성·Warmup·노이즈 제거
- 8 성능 모델링 — Amdahl·Gustafson·Roofline Model 적용
- 9 프로파일링 기법 개요 — Sampling vs Instrumentation·PGO·LTO
- 10 CPU 파이프라인 분석 — 5-stage·Cortex-M·Cortex-A 비교
- 11 Pipeline Stall 분석 — Data·Structural·Control Hazard·Forwarding
- 12 Branch Prediction 분석 — Static·2-bit·BTB·BHT·Mispredict 비용
- 13 Speculative Execution 분석 — OoO·Reorder Buffer·Register Renaming
- 14 CPU Cache 기초 — L1·L2·L3·Set Associative·Replacement Policy
- 15 Cache Miss 3C Model 분석 — Compulsory·Capacity·Conflict
- 16 Cache Line 최적화 — Alignment·Prefetch·False Sharing 처리
- 17 메모리 대역폭 분석 — STREAM·Roofline·Bus Saturation 측정
- 18 SIMD·NEON 활용 — 128-bit Vector·Auto-Vectorization·SVE/SVE2
- 19 PMU·HPM 하드웨어 카운터 분석 — 정밀 성능 진단
- 20 임베디드 Bus Architecture — AHB·AXI·CHI 진화와 5-Channel
- 21 Bus Contention 진단 — Arbitration·QoS·Starvation 측정
- 22 DMA 성능 최적화 — Burst·Scatter-Gather·Chain·Cache 일관성
- 23 DMA vs CPU Copy 성능 비교 — Break-even·Setup Overhead 실측
- 24 Interrupt Latency 분석 — 진입·종료·Tail-Chaining·Late Arrival
- 25 Interrupt Storm 처리 — NAPI·Rate-Limit·Polling 전환
- 26 MMIO 접근 성능 — Cache Policy·Write-Combining·Volatile·Barrier
- 27 Peripheral Clock 분석 — PLL·Divider·Gating·DVFS
- 28 Power vs Performance 트레이드오프 — DVFS·Race-to-Idle·Big.LITTLE
- 29 Thermal Throttling 분석 — Junction Temp·Trip Point·냉각
- 30 CXL Interconnect 분석 — AI 시대 메모리 대역폭 확장
- 31 Concurrency 기초 — Concurrency vs Parallelism·Race·Memory Model
- 32 False Sharing 진단 — Cache Line Ping-Pong·Padding·측정
- 33 Lock Contention 분석 — Wait·Hold·Convoy·측정 기법
- 34 Spinlock 성능 분석 — Spin-Wait vs Context Switch·Ticket·MCS
- 35 Mutex 성능 분석 — Futex·Adaptive·Priority Inheritance
- 36 Reader-Writer Lock 성능 — Reader/Writer Priority·RCU·Seqlock
- 37 Lock-Free 자료구조 성능 — CAS·ABA·Hazard Pointer·Epoch Reclamation
- 38 Memory Ordering 분석 — Acquire·Release·Seq-Cst·ARM Relaxed Model
- 39 Cache Coherency 프로토콜 — MESI·MOESI·Snoop·Directory
- 40 SMP 성능 분석 — Per-Core·Affinity·Load Balance·Scalability
- 41 Linux perf 기초 — stat·record·report 활용
- 42 Linux perf 고급 — Raw Event·Tracepoint·perf script
- 43 ftrace 활용 — function·function_graph·latency tracer
- 44 eBPF·bpftrace 동적 트레이싱 — 커널 무수정 관측
- 45 Flamegraph 분석 — On-CPU·Off-CPU·Differential
- 46 ARM DS·Lauterbach 분석 — Hardware Trace 전문 도구
- 47 Bare-metal 프로파일링 — GPIO·DWT·SysTick·ITM 활용
- 48 NVIDIA Nsight Systems — GPU·NPU 포함 시스템 분석
- 49 모던 프로파일러 비교 — Tracy·Hotspot·uftrace·Coz
- 50 연속 프로파일링 — Parca·Pixie·Pyroscope·Tetragon
- 51 실전 사례 — ISR Latency 100µs Deadline Miss 추적
- 52 실전 사례 — Matrix Multiply가 예상의 10배 느린 이유
- 53 실전 사례 — 8-core가 4-core를 넘으면 throughput이 떨어지는 이유
- 54 실전 사례 — 카메라 1080p 60fps가 30fps로 떨어지는 이유
- 55 CXL.mem 지연·대역폭 실측 — Direct·Switch·Pooled 토폴로지 비교
- 56 CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용
- 57 실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복
관련 글
실전 사례 — ISR Latency 100µs Deadline Miss 추적
산업용 센서 보드에서 산발적으로 발생한 ISR latency spike. 가설 두 개를 거쳐 SD 카드 드라이버를 범인으로 확정한 과정.
같은 시리즈에서 이어 읽기
실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복
70B 모델 KV cache가 HBM 한계를 넘어 throughput이 무너졌을 때, CXL.mem 256 GB pool 추가로 회복한 실전 케이스.
같은 시리즈에서 이어 읽기
CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용
CXL.mem 환경 성능 도구 — cxl-cli 토폴로지·DAMON page activity·perf-mem로 보는 CXL 트래픽·numastat 통계.
같은 시리즈에서 이어 읽기