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
- 1Embedded 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
- 10CPU 파이프라인 분석 — 5-stage·Cortex-M·Cortex-A 비교
- 11Pipeline Stall 분석 — Data·Structural·Control Hazard·Forwarding
- 12Branch Prediction 분석 — Static·2-bit·BTB·BHT·Mispredict 비용
- 13Speculative Execution 분석 — OoO·Reorder Buffer·Register Renaming
- 14CPU Cache 기초 — L1·L2·L3·Set Associative·Replacement Policy
- 15Cache Miss 3C Model 분석 — Compulsory·Capacity·Conflict
- 16Cache Line 최적화 — Alignment·Prefetch·False Sharing 처리
- 17메모리 대역폭 분석 — STREAM·Roofline·Bus Saturation 측정
- 18SIMD·NEON 활용 — 128-bit Vector·Auto-Vectorization·SVE/SVE2
- 19PMU·HPM 하드웨어 카운터 분석 — 정밀 성능 진단
- 20임베디드 Bus Architecture — AHB·AXI·CHI 진화와 5-Channel
- 21Bus Contention 진단 — Arbitration·QoS·Starvation 측정
- 22DMA 성능 최적화 — Burst·Scatter-Gather·Chain·Cache 일관성
- 23DMA vs CPU Copy 성능 비교 — Break-even·Setup Overhead 실측
- 24Interrupt Latency 분석 — 진입·종료·Tail-Chaining·Late Arrival
- 25Interrupt Storm 처리 — NAPI·Rate-Limit·Polling 전환
- 26MMIO 접근 성능 — Cache Policy·Write-Combining·Volatile·Barrier
- 27Peripheral Clock 분석 — PLL·Divider·Gating·DVFS
- 28Power vs Performance 트레이드오프 — DVFS·Race-to-Idle·Big.LITTLE
- 29Thermal Throttling 분석 — Junction Temp·Trip Point·냉각
- 30CXL Interconnect 분석 — AI 시대 메모리 대역폭 확장
- 31Concurrency 기초 — Concurrency vs Parallelism·Race·Memory Model
- 32False Sharing 진단 — Cache Line Ping-Pong·Padding·측정
- 33Lock Contention 분석 — Wait·Hold·Convoy·측정 기법
- 34Spinlock 성능 분석 — Spin-Wait vs Context Switch·Ticket·MCS
- 35Mutex 성능 분석 — Futex·Adaptive·Priority Inheritance
- 36Reader-Writer Lock 성능 — Reader/Writer Priority·RCU·Seqlock
- 37Lock-Free 자료구조 성능 — CAS·ABA·Hazard Pointer·Epoch Reclamation
- 38Memory Ordering 분석 — Acquire·Release·Seq-Cst·ARM Relaxed Model
- 39Cache Coherency 프로토콜 — MESI·MOESI·Snoop·Directory
- 40SMP 성능 분석 — Per-Core·Affinity·Load Balance·Scalability
- 41Linux perf 기초 — stat·record·report 활용
- 42Linux perf 고급 — Raw Event·Tracepoint·perf script
- 43ftrace 활용 — function·function_graph·latency tracer
- 44eBPF·bpftrace 동적 트레이싱 — 커널 무수정 관측
- 45Flamegraph 분석 — On-CPU·Off-CPU·Differential
- 46ARM DS·Lauterbach 분석 — Hardware Trace 전문 도구
- 47Bare-metal 프로파일링 — GPIO·DWT·SysTick·ITM 활용
- 48NVIDIA 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로 떨어지는 이유
- 55CXL.mem 지연·대역폭 실측 — Direct·Switch·Pooled 토폴로지 비교
- 56CXL 성능 프로파일링 도구 — 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 통계.