Prezentacja barcampu firmy Semihalf.
Opowiadamy jak działa system ARM CoreSight. Przedstawiamy jego komponenty oraz zasady współdziałania i konfigurowania. Pokazujemy sposób integracji systemu CoreSight z Linuxowym narzędziem Perf oraz przykłady jego użycia podczas profilowania kodu.
3. Plan prezentacji
● Dlaczego potrzebujemy wsparcia w SOC?
● Czym jest PMU
● Perf
○ profilowanie statystyczne
○ profilowanie dynamiczne (eventy)
● Coresight
4. PMU - Performance Monitor Unit
1. Proste zliczanie “zdarzeń”
2. Wewnętrzna szyna “event interface” z
kodowaniem per bit per clk
a. Branch
b. Cache miss
c. etc ...
3. Kilka (3 do 6) liczników
a. każdy z nich może liczyć tylko 1 event
b. read/write/reset
c. overflow IRQ
4. Rejestry dostępne przez
a. root/user
b. MRS/MSR/MMIO
c. JTAG
Core
CPU
& other
components
PMU
Event counter
Cycle counter
PMU control
registers
nPMUIRQ
CLKIN
Interrupt and
overflow registers
Eventtype
Event counter
Event counter
7. Linux Perf
1. Perf - cała rodzina narzędzi zebrana w postaci jednego
programu
a. HW events
b. SW events
i. static tracepoints
ii. dynamic probes
c. wrapper for ftrace and eBPF
d. and more
2. W kontekście PMU omówimy wyłącznie pracę w trybie
a. statystycznym - całościowe statystyki
b. eventowym - okresowe przerywanie programu
i rejestrowanie stanu CPU
8. perf stat vs perf record
root@rad-desktop:/home/rad# perf list
branch-instructions OR branches [Hardware event]
branch-misses [Hardware event]
cache-misses [Hardware event]
cache-references [Hardware event]
cpu-cycles OR cycles [Hardware event]
[...]
alignment-faults [Software event]
bpf-output [Software event]
context-switches OR cs [Software event]
cpu-clock [Software event]
cpu-migrations OR migrations [Software event]
dummy [Software event]
emulation-faults [Software event]
major-faults [Software event]
minor-faults [Software event]
page-faults OR faults [Software event]
task-clock [Software event]
[...]
L1-dcache-load-misses [Hardware cache event]
L1-dcache-loads [Hardware cache event]
L1-dcache-prefetch-misses [Hardware cache event]
LLC-load-misses [Hardware cache event]
LLC-loads [Hardware cache event]
LLC-stores [Hardware cache event]
Czas uruchomienia programu
Start Stop
“Free-run profiling” - perf stat
Czas uruchomienia programu
Start Stop
“Sampling based profiling” - perf record
IRQ raz na N zdarzeń
to nie musi być
przerwanie od clock!!
10. PMU - niedokładności
1. Zaprojektowany aby zliczać ile razy coś się wydarzyło,
nie zaś w dokładnie którym miejscu programu.
2. PMU potrafi generować IRQ przy przepełnieniu
licznika, np w celu wykonywania “samplowania stanu
CPU raz na N zdarzeń”
3. Przerwania przechwytywane są przez kernel
armv8pmu_handle_irq() -> perf_event_overflow() ->
event->overflow_handler(event, data, regs) -> ?
np eBPF handler
4. Przyjęcie przerwania HW jest opóźnione
5. Przez efekty superskalarne PC zazwyczaj nie wskazuje
na instrukcje wywołującą event
(reservation stations, reorder buffer)
6. Throttling IRQ -> perf_adjust_period()
opcje -c & -F (standardowo 1000Hz lub 1000sampl/s)
s
t
a
l
l
dependencyjbe ...
mov or
ret?
Cycle
cmp ... cache miss
xor %eax, %eax
cmp %rdi, array_size(%rip)
jbe .L1
mov array(%rdi), %eax
.L1:
ret
xor ...
stall
event
PC w IRQ
12. PMU - podsumowanie
Zaprojektowany aby zliczać ile razy coś się wydarzyło a nie zaś w dokładnie którym miejscu
programu.
1. Tylko niewielka (3 do 6) liczba liczników w sprzęcie
2. Kernel musi zarządzać PMU przy zmianach kontekstu (np śledzenie różnych aplikacji, śledzenie
kernela, śledzenie VM lub jej części w userspace)
3. Przez efekty superskalarne przerwania przepełnienia są zazwyczaj przesunięte w czasie
4. Nie potrafi generować “śladów” wykonania programu (np śladu skoków które doprowadziły do
zdarzenia) (x86 jest pod tym względem lepszy).
5. PMU nie dostarcza żadnych detali na temat stanu procesora przy “evencie”.
Informacje które da się zebrać są wyłącznie z kontekstu przerwania IRQ.
CoreSight na ratunek
14. Plan
● Co to jest CoreSight ?
● Zalety CoreSight
● Architektura
○ Komponenty
○ Konfiguracja
○ Synchronizacja
● Zasada działania
● Linux & CoreSight
○ Konfiguracja Linuxa
○ Integracja z narzędziem ‘perf’
○ Co oferuje ‘perf’ i jakie mamy możliwości ?
○ Przykład użycia
16. Co to jest CoreSight ?
● Zestaw komponentów (IP core) dodanych do SoC na poziomie implementacji
krzemu
● IP bloki zapewniają sprzętowe wsparcie dla śledzenia tego co robi SoC
○ dedykowana szyna (ATB) dzięki której Coresight nie wpływa na wydajność
● Nie ma potrzeby kosztownych zewnętrznych narzędzi
● Komponenty CoreSight można selektywnie konfigurować, aktywować i
dezaktywować
● Synchronizacja między komponentami pozwala na debugowanie
skomplikowanych scenariuszy (nie wszystko jeszcze wspierane w Linuxie)
● CoreSight współpracuje z zewnętrznym debugerem JTAG
17. Dlaczego CoreSight jest taki przydatny ?
● Przewaga nad dotychczasowymi rozwiązaniami
○ Mnogość konfiguracji i scenariuszy CoreSight - niemożliwa do zaimplementowania za pomocą
JTAG
○ Możliwość synchronizacji za pomocą zdarzeń wyzwalanych z różnych źródeł
○ Konfiguracja z poziomu maszyny, którą debugujemy (self-hosted) lub zewnętrznego
urządzenia JTAG
● Dwa formaty dla źródła danych
○ STM - dostęp do pamięci
○ ETM - wykonywane instrukcje
● Niektóre scenariusze nie mogą sobie pozwolić na zatrzymanie maszyny gdy
nastąpi oczekiwane zdarzenie
18. Dlaczego CoreSight jest taki przydatny ?
● Niektóre maszyny po prostu nie mają portu JTAG
● Zaawansowane możliwości
○ Komparatory - pojedynczy lub zakres adresów
○ Śledzenie wybranego procesu, maszyny wirtualnej
○ Śledzenie wybranego poziomu uprzywilejowania: aplikacja, OS, hypervisor, secure FW
○ Możliwość kombinacji każdego z powyższych opcji
● Możliwość śledzenia ścieżki instrukcji jakie zostały wykonane przez CPU
(ślad programu)
19. Architektura
● Komponenty są podzielone na 4 kategorie:
○ źródło, link, odbiornik, synchronizator
● Źródło
○ ETM (Embedded Trace Macrocell) - protokół PFT
○ STM (System Trace Macrocell) - protokół STP
● Link
○ Replikator - duplikuje strumień danych
○ Funnel - agreguje strumienie danych do jednego strumienia
● Odbiornik
○ ETB (Embedded Trace Buffer)
○ ETR (Embedded Trace Router)
● Synchronizator
○ CTI (Cross Trigger Interface) - komunikacja i synchronizacja między komponentami
21. Jak działa CoreSight ?
● Każdy CPU jest skojarzony z komponentem ETM
● Dane z ETM są agregowane (Funnel), rozdzielane (Replicator) tak aby trafiły
do miejsca gdzie będą analizowane
● Dane mogą być przechowywane w kilku komponentach w zależności od
scenariusza i ilości danych ETB/ETR/TPIU
● OS na podstawie opisu w DTS, inicjalizuje każdy z komponentów w
odpowiednich sterownikach i tworzy wewnętrzne struktury opisujące topologie
i wzajemne relacje relacje
● Każdy z komponentów jest konfigurowany przez OS podczas śledzenia CPU
● Możliwe jest określenie warunków dla których zbierane są dane
● Śledzenia CPU nie wpływa na jego wydajność poza pewnymi wyjątkami
23. Dwa formaty danych: STM vs ETM
● STM: dostępy do pamięci (protokół STP)
● ETM: reprezentuje ścieżkę wykonanych instrukcji CPU (protokół PFT)
CPU ETM
kernel
User
space
kernel
STM
SW writes
PFT
STP
ETF/ETR
TPIU
CPU instr flow
24. ETM - dane wyjściowe
● Dane z ETM są skompresowane do pakietów tak aby zredukować ilość
potrzebnego miejsca na ich przechowywanie
● Tylko waypointy są rejestrowane:
○ Punkty gdzie CPU zmienia ścieżkę wykonywania rozkazów
○ Rozgałęzienia, wyjątki, powroty z funkcji, punkty synchronizacji, bariery
● Każdy waypoint oznacza, że instrukcje między tym waypointem i poprzednim
zostały wykonane
● Waypointy w połączeniu z obrazem binarnym programu np. vmlinux
jednoznacznie wyznaczają ścieżkę i instrukcje jakie zostały wykonane
● Atom to rodzaj waypointu, który w zależności od skorelowanej instrukcji
implikuje kierunek wykonywanych skoków w programie (branches)
25. ETM - dekodowanie danych
● Problematyczne i złożone przez swoją skompresowaną naturę
● Linaro, TI, ARM stworzyli i utrzymuje otwartą bibliotekę OpenCSD
● CoreSight jest zintegrowany z perfem
● Podczas kompilacji perf linkuje się z biblioteką OpenCSD
26. ● OpenCSD Library
$ git clone https://github.com/Linaro/OpenCSD.git -b master
$ cd OpenCSD/decoder/build/linux
$ make -j<CPU_NR> && make install
● Mainline kernel and perf tool
$ git clone https://github.com/torvalds/linux.git
$ make menuconfig
// make sure required configs are enabled
// CONFIG_CORESIGHT=y
// CONFIG_CORESIGHT_LINKS_AND_SINKS=y
// CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
// CONFIG_CORESIGHT_SINK_TPIU=y
// CONFIG_CORESIGHT_SINK_ETBV10=y
// CONFIG_CORESIGHT_SOURCE_ETM4X=y
// CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y
// CONFIG_CORESIGHT_STM=y
// build and install kernel
$ make -j && make -j modules_install && make install
// build and isntall perf tool
$ make -j<CPU_NR> -C tools/perf/ && make -C tools/perf/ install
● Coresight Topology - Firmware & Device Tree
Linux & CoreSight
27. Linux & CoreSight
sdhci-pltfm: SDHCI platform and OF driver helper
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
coresight-etm4x 22040000.etm: ETM 4.0 initialized
coresight-etm4x 22140000.etm: ETM 4.0 initialized
coresight-etm4x 23040000.etm: ETM 4.0 initialized
coresight-etm4x 23140000.etm: ETM 4.0 initialized
coresight-etm4x 23240000.etm: ETM 4.0 initialized
coresight-etm4x 23340000.etm: ETM 4.0 initialized
usb 1-1: new high-speed USB device number 2 using ehci-platform
NET: Registered protocol family 17
9pnet: Installing 9P2000 support
root@ubuntu:~# ls /sys/bus/coresight/devices/
20010000.etf 220c0000.cluster0-funnel 23240000.etm 20030000.tpiu 22140000.etm 23340000.etm
20040000.main-funnel 23040000.etm coresight-replicator 20070000.etr 230c0000.cluster1-funnel
22040000.etm 23140000.etm
root@ubuntu:~#
28. Perf & CoreSight
● Perf - dojrzałe i szeroko używane narzędzie
● Framework oferujący szereg mechanizmów do śledzenia i analizowania
● CoreSight jest traktowany jako dodatkowy silnik PMU ‘cs_etm’
● Perf abstrachuje złożoną konfigurację CoreSight do intuicyjnego interfejsu
29. Perf & CoreSight
● CoreSight PMU działa podobnie jak inne PMU
./perf record -e event_name/{options}/ --perf-thread ./main
● Najprostsza forma
./perf record -e cs_etm/@20070000.etr/ --perf-thread ./main
● Komponent który zbiera dane musi być wskazany explicite:
root@ubuntu:~$ ls /sys/bus/coresight/devices/
20010000.etf 20040000.main-funnel 22040000.etm
22140000.etm
230c0000.cluster1-funnel 23240000.etm coresight-replicator
20030000.tpiu
20070000.etr 220c0000.cluster0-funnel 23040000.etm
23140000.etm
30. Perf & CoreSight
● Najprostsza forma generuje zwykle za dużo danych
● Można zawęzić śledzenie CPU do przestrzeni kernel/user space
./perf record -e cs_etm/@20070000.etr/u --perf-thread ./main
./perf record -e cs_etm/@20070000.etr/k --perf-thread ./main
./perf record -e cs_etm/@20070000.etr/h --perf-thread ./main
31. Perf & CoreSight & Filtry
● Wbudowane komparatory adresów pomagają dodatkowo zawęzić obszar śledzenia
○ Śledzenie między wyznaczonym obszarem adresów dla kernel/user space (Range Filters)
■ *Nie uwzględnia* skoków poza wyznaczony zakres
$ perf record -e cs_etm/@20010000.etr/k --filter 'filter 0xffffff8008562d0c/0x48' --per-thread ./main
$ perf record -e cs_etm/@20070000.etr/u --filter 'filter 0x72c/0x40@/opt/lib/libcstest.so.1.0' --per-thread ./main
○ Śledzenie między wyznaczonym jednym a drugim adresem (Start/Stop Filters)
■ *Uwzględnia* skoków poza wyznaczony zakres
$ perf record -e cs_etm/@20070000.etr/k --filter
'start 0xffffff800856bc50,stop 0xffffff800856bcb0,
start 0xffffff8008562d0c,stop 0xffffff8008562d30' --per-thread ./main
$ perf record -e cs_etm/@20070000.etr/u --filter
'start 0x72c@/opt/lib/libcstest.so.1.0'
'stop 0x26@/main' --per-thread ./main
32. Perf & CoreSight & Filtry
● Ilość komparatorów jest ograniczona przez projektanta krzemu, zwykle 8 komparatorów
● Komparatory różnego typu można używać w jednej sesji
$ perf record -e cs_etm/@20070000.etr/k --filter
'start 0xffffff800856bc50,stop 0xffffff800856bcb0', // start/stop filter
0x72c/0x40@/opt/lib/libcstest.so.1.0' // Range
--per-thread ./main
33. Perf & CoreSight & Analiza
● Dane zbierane są jak zawsze do pliku ‘perf.data’
$ perf report --dump perf.data
CoreSight ETM Trace data: size 3744 bytes
Idx:0; ID:16; I_NOT_SYNC : I Stream not synchronised
Idx:2; ID:16; I_ASYNC : Alignment Synchronisation.
Idx:16; ID:16; I_TRACE_INFO : Trace Info.; INFO=0x0
Idx:18; ID:16; I_TRACE_ON : Trace On.
Idx:19; ID:16; I_CTXT : Context Packet.; Ctxt: AArch64,EL2, NS;
Idx:21; ID:16; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0xFFFF0000088599C8;
Idx:30; ID:16; I_ATOM_F1 : Atom format 1.; N
Idx:32; ID:16; I_TIMESTAMP : Timestamp.; Updated val = 0x49dbeb0603d6
Idx:40; ID:16; I_ATOM_F2 : Atom format 2.; NE
Idx:41; ID:16; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0xFFFF000008860878;
Idx:51; ID:16; I_ATOM_F2 : Atom format 2.; NE
Idx:52; ID:16; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0xFFFF0000088610C0;
Idx:61; ID:16; I_ATOM_F1 : Atom format 1.; E
Idx:62; ID:16; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0xFFFF000008859D30;
34. Przykład użycia
“main.c”
#include <stdio.h>
int coresight_test1(int val);
int main(void)
{
int val = coresight_test1(10);
printf("val: %dn", val);
return 0;
}
“libcstest.c”
int coresight_test1(int val)
{
int i;
/*
* A simple loop forcing the
* instruction pointer to move
* around.
*/
for (i = 0; i < 5; i++)
val += 2;
return val;
}
36. Przykład użycia - trace session
● Dane zbierane są jak zawsze do pliku ‘perf.data’
$ root@ubuntu:~# perf record -e cs_etm/@20070000.etr/u --filter 'filter
0x72c/0x40@/opt/lib/libcstest.so.1.0' --per-
thread ./main
val: 20
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.002 MB perf.data ]
$ root@ubuntu:~# ls -l perf.data
-rw------- 1 root root 8176 Sep 7 20:17 perf.data
37. Przykład użycia - dekodowanie i analiza
$ perf report --stdio // by default file “perf.data” is used
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 8 of event 'instructions:u'
# Event count (approx.): 55
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................ ......................
#
81.82% 81.82% main libcstest.so.1.0 [.] 0x000000000000073c
7.27% 7.27% main libcstest.so.1.0 [.] 0x000000000000072c
5.45% 5.45% main libcstest.so.1.0 [.] 0x0000000000000754
5.45% 5.45% main libcstest.so.1.0 [.] 0x0000000000000760
38. Przykład użycia - dekodowanie i analiza
$ perf script
main 1796 4 instructions:u: 7fb19c972c [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 3 instructions:u: 7fb19c9754 [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 9 instructions:u: 7fb19c973c [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 9 instructions:u: 7fb19c973c [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 9 instructions:u: 7fb19c973c [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 9 instructions:u: 7fb19c973c [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 9 instructions:u: 7fb19c973c [unknown] (/opt/lib/libcstest.so.1.0)
main 1796 3 instructions:u: 7fb19c9760 [unknown] (/opt/lib/libcstest.so.1.0)
VMA portion ELF portion