Programowanie Systemów Wbudowanych

Transkrypt

Programowanie Systemów Wbudowanych
Programowanie Systemów Wbudowanych
Zarzadzanie
˛
pamieci
˛ a˛
Iwona Kochańska
Katedra Systemów Elektroniki Morskiej
WETI PG
May 24, 2016
Pamieć
˛ wirtualna
I
I
Przestrzeń adresowa pamieci
˛ wirtualnej: od zera do 0xffffffff (dla
procesorów 32-bitowych), podzielona na strony o rozmiarze 4 kB
Przestrzeń adresowa podzielona na przestrzeń użytkownika
(user space) i przestrzeń jadra
˛
(kernel space)
GUT – Intel 2015/16
2/40
Pamieć
˛ wirtualna
I
Podział miedzy
˛
przestrzeń użytkownika a przestrzeń jadra:
parametr PAGE_OFFSET konfiguracji jadra
˛
I
I
I
I
typowy system 32-bitowy: PAGE_OFFSET = 0xc0000000, niższe
3GB - przestrzeń użytkownika
przestrzeń użytkownika alokowana dla procesu
przestrzeń jadra
˛
- wspólna dla wszystkich procesów.
Memory Management Unit (MMU) - mapowanie adresów w
przestrzeni wirtualnej na adresy w pamieci
˛ fizycznej
GUT – Intel 2015/16
3/40
Pamieć
˛ wirtualna
Każda strona pamieci
˛ wirtualnej może być:
I
niemapowana (próba dostepu
˛
-> SIGSEGV -> komunikat
segmentation fault)
I
mapowana na strone˛ fizyczna˛ pamieci
˛ prywatna˛ dla procesu
I
mapowana na strone˛ fizyczna˛ pamieci
˛ współdzielona˛ z innym
procesem
I
mapowana i współdzielona z flaga˛ “copy on write”
I
I
gdy istnieje potrzeba współdzielenia wzglednie
˛
dużej ilości danych,
co do których nie ma pewności, że zostana˛ zmodyfikowane przez
używajace
˛ je obiekty
zamiast rzeczywistego, kosztownego kopiowania pamieci
˛ zwracany
jest wskaźnik do oryginalnych danych; kopiowanie jest
wykonywane dopiero, gdy zachodzi potrzeba ich modyfikacji.
GUT – Intel 2015/16
4/40
Pamieć
˛ wirtualna
Każda strona pamieci
˛ wirtualnej może być:
I
mapowana na strone˛ fizyczna˛ pamieci
˛ używana˛ przez jadra
˛
I
jadro
˛
może dodatkowo mapować strony p. wirtualnej na obszary
pamieci
˛ zarezerwowane dla np. buforów pamieci
˛ sterowników
Zalety:
I
niepoprawne odwołania do pamieci
˛ przechwytywane i
sygnalizowane przez SIGSEGV
I
proces działa we własnej przestrzeni pamieci, odizolowany od
innych procesów
I
efektywne wykorzystanie pamieci
˛ - współdzielenie cz˛eści kodu i
danych ( np. bibliotek)
I
możliwość zwiekszenia
˛
ilości pamieci
˛ poprzez pliki wymiany
(swap files)
GUT – Intel 2015/16
5/40
Pamieć
˛ wirtualna
Wady:
I
trudno ustalić, jakie jest aktualne zużycie pamieci
˛ (przez
aplikacje)
˛
I
“overcommit” - praktyka przedzielania pamieci
˛ wirtualnej bez
gwarancji, że dostepna
˛
jest odpowiednia ilość pamieci
˛ fizycznej
I
opóźnienia wprowadzane przez zarzadzanie
˛
pamieci
˛ a˛ i obsługe˛
wyjatków
˛
(page faults)
GUT – Intel 2015/16
6/40
Obszar pamieci
˛ jadra
˛
Przestrzeń pamieci jadra
˛
- każdej alokacji w przestrzeni wirtualnej
odpowiada przestrzeń fizyczna!
I
jadro
˛
(kod i dane załadowane z obrazu jadra
˛
podczas rozruchu
systemu)
I
I
segmenty: .text, .init, .data, .bss
pamieć
˛ alokowana przez kmalloc()
I
slab allocator - efektywny mechanizm alokacji;
I
I
eliminuje fragmentacje˛ pamieci
˛
alokacja pamieci
˛ zawierajacej
˛ obiekty danych do reużycia dla
obiektów danych tego samego typu
GUT – Intel 2015/16
7/40
Obszar pamieci
˛ jadra
˛
I
pamieć
˛ alokowana przez vmalloc()
I
wieksze
˛
obszary pamieci
˛ niż kmalloc() (przestrzeń adresowa
wirtualna - ciagła,
˛
ale fizyczna - niekoniecznie)
I
pamieć
˛ dla sterowników urzadze
˛
ń
I
moduły jadra
˛
GUT – Intel 2015/16
8/40
Ile pamieci
˛ używa jadro?
˛
I
rozmiar obrazu jadra
˛
I
I
zwykle jadro
˛
jest małe w porównaniu z całkowita˛ ilościa˛ pamieci
˛
budowa małego jadra
˛
( Linux-tiny, Linux Kernel Tinification), projekt
https://tiny.wiki.kernel.org/.
GUT – Intel 2015/16
9/40
Ile pamieci
˛ używa jadro?
˛
I
Odczyt /proc/meminfo
GUT – Intel 2015/16
10/40
Ile pamieci
˛ używa jadro?
˛
Kernel memory usage to suma:
I
Slab: pamieć
˛ alokowana przez slab allocator
I
wiecej
˛
informacji - odczyt /proc/slabinfo
I
KernelStack: przestrzeń adresowa stosu
I
PageTables: pamieć
˛ do przechowywania tablic stronicowania
I
VmallocUsed: pamieć
˛ alokowana przez vmalloc()
I
wiecej
˛
informacji - odczyt /proc/vmallocinfo
GUT – Intel 2015/16
11/40
Ile pamieci
˛ używa jadro?
˛
lsmod - ile pamieci
˛ zużywa kod i dane modułów jadra?
˛
GUT – Intel 2015/16
12/40
Obszar pamieci
˛ użytkownika
I
Stronicowanie na żadanie
˛
(Demand-paging) - Linux mapuje
strony pamieci
˛ fizycznej tylko wtedy, gdy program odwołuje sie˛
do odpowiedniego miejsca w pamieci
˛ wirtualnej
malloc(3) zwraca wskaźnik do pamieci
˛ wirtualnej
operacja odczytu/zapisu przechwytywana przez jadro
˛
page fault
jadro
˛
znajduje obszar pamieci
˛ fizycznej
i dodaje go 13/40
do tablicy stronicowania
GUT – Intel 2015/16
Obszar pamieci
˛ użytkownika
I
Bład
˛ stronicowania (page fault) - gdy jadro
˛
przechwytuje
dostep
˛ do strony pamieci
˛ nie mapowanej na pamieć
˛ fizyczna˛
I
Dwa rodzaje błedów
˛
stronicowania:
I
I
minor - rozwiazaniem
˛
jest znalezienie przez jadro
˛
wolnego
obszaru pamieci
˛ fizycznej i powiazanie go z przestrzenia˛ adresowa˛
procesu w pamieci
˛ wirtualnej
major - pamieć
˛ wirtualna jest mapowana na plik (np. za pomoca˛
mmap(2)). Próba odczytu z takiej pamieci:
˛
I
I
jadro
˛
musi znaleźć obszar pamieci
˛ fizycznej
jadro
˛
musi wypełnić pamieć
˛ fizyczna˛ danymi z pliku
GUT – Intel 2015/16
14/40
Mapa pamieci
˛ procesu
Dostep
˛ do mapy pamieci
˛ procesu - przez system plików proc
I
Przykład: mapa pamieci
˛ procesu init (PID 1)
...
I Pierwsze trzy kolumny: adres poczatku
˛
i końca pamieci
˛ wirtualnej, flagi
uprawnień: r = read w = write x = execute s = shared p = private (copy on write)
I Mapowanie pamieci
˛ zwiazanej
˛
z plikiem: kolumna 4: przesuniecie
˛
wzgledem
˛
poczatku
˛
pliku, kolumna 5: numer urzadzenia
˛
blokowego, kolumna 6: inod pliku,
kolumna 7: nazwa pliku
GUT – Intel 2015/16
15/40
Partycja wymiany (Swap)
Partycja wymiany służy do tymczasowego przechowywania danych
w sytuacji, gdy ich ilość przekracza zasoby wolnej pamieci
˛ RAM lub
gdy z różnych powodów korzystniej jest przechowywać je na dysku
twardym
I
zwiekszenie
˛
efektywnego rozmiaru pamieci
˛ fizycznej
I
koszt obsługi partycji wymiany jest duży w systemie o małej
ilości pamieci
˛ fizycznej
I
mechanizm rzadko używany w systemach wbudowanych (swap
nie sprawdza sie˛ z nosnikami flash)
GUT – Intel 2015/16
16/40
Wykorzystanie partycji wymiany do kompresji pamieci
˛
(zram)
I
sterownik zram tworzy urzadzenia
˛
blokowe: /dev/zram0,
/dev/zram1, itd.
I
zawartość pamieci
˛ jest kompresowana przed zapisem do zram
I
współczynnik kompresji: 30% - 50%
I
całkowity zysk wolnej pamieci:
˛ 10%
I
koszt: kompresja (przetwarzanie), zwiekszone
˛
zużycie mocy
I
stosowane w niektórych urzadzeniach
˛
Android
GUT – Intel 2015/16
17/40
Mapowanie pamieci
˛
I
Proces rozpoczyna swoje życie z pewna˛ ilościa˛ pamieci
˛
I
I
I
I
segment kodu programu (text)
segment danych (data)
biblioteki wspóldzielone
Proces może alokować dodatkowa pamieć
˛
I
I
na stosie (heap), podczas działania, za pomoca˛ malloc(3);
domyślnie bez ograniczeń
na stercie (stack), za pomoca˛ alloca(3); domyślnie - max. 8 MB,
Alokacja przekraczajaca
˛ limit -> sygnał SIGSEGV
I
Ładowanie bibliotek współdzielonych - dlopen(3).
GUT – Intel 2015/16
18/40
Mapowanie pamieci
˛ (mmap)
I
Proces może też alokować pamieć
˛ za pomoca˛ mmap(2)
mapuje length bajtów pamieci
˛ z pliku od deskryptorze fd,
poczawszy
˛
od offset w pliku i zwraca wskaźnik do obszaru
pamieci;
˛
prot - parametr ochrony (kombinacja read, write, execute i flagi
MAP_SHARED lub MAP_PRIVATE)
GUT – Intel 2015/16
19/40
Mapowanie pamieci
˛ (mmap)
I
Alokacja pamieci
˛ prywatnej
I
I
I
flaga MAP_ANONYMOUS i fd = -1.
malloc(3) w glibc alokuje pamieć
˛ do 128kB, potem woła mmap
Alokacja pamieci
˛ współdzielonej
I
flaga MAP_SHARED i fd = shm_open()
shm_open(3) - create POSIX shared memory objects
GUT – Intel 2015/16
20/40
Mapowanie pamieci
˛ (mmap)
I
Alokacja pamieci
˛ urzadzenia
˛
I
I
I
dokładna implementacja - zależna od sterownika
Przykład 1: Linux frame buffer, /dev/fb0. Interfejs zdefiniowany w
/usr/include/linux/fb.h, funkcja ioctl zwraca rozmiar ekranu i liczbe˛
bitów na pixel
mmap - prośba do sterownika wideo o udostepnienie
˛
bufora ramek
dla aplikacji do odczytu/zapisu
Przykład 2: interfejs strumieniowy wideo, V4L2
(/usr/include/linux/videodev2.h)
GUT – Intel 2015/16
21/40
Ile pamieci
˛ używa aplikacja?
I
polecenie free - ile wolnej pamieci
˛ widzi jadro
˛
I
jadro
˛
wykorzystuje wolna˛ pamieć
˛ na bufory i cache-e, które
moga˛ być zwolnione/skompresowane w każdej chwili
GUT – Intel 2015/16
22/40
Ile pamieci
˛ używa aplikacja?
I
Wymuszenie zwolnienia cache-ów:
echo 3 > /proc/sys/vm/drop_caches
Numer 3 (lub 1 lub 2) - maska bitowa:
GUT – Intel 2015/16
23/40
Ile pamieci
˛ używa aplikacja?
Dwie metryki ilości pamieci
˛ używanej przez proces
I
Vss (virtual set size) - nazywana VSZ w komendzie ps i VIRT w
top
I
I
całkowita ilość pamieci
˛ mapowanej przez proces (suma obszarów
pokazanych w /proc/<PID>/maps)
Rss (resident memory size) - nazywana RSS w ps i RES w top
I
I
całkowita ilość pamieci
˛ mapowanej na pamieć
˛ fizyczna˛
wartość wieksza
˛
od rzeczywistej pamieci
˛ fizycznej zużywanej
przez proces - obszary współdzielone policzone wielokrotnie!
GUT – Intel 2015/16
24/40
Komenda ps
I
Komendy top i ps z BusyBox - ograniczona ilość informacji
I
Pakiet procps - pełne wersje top i ps
I
Komenda ps - pokazuje VSZ i RSS
GUT – Intel 2015/16
25/40
Komenda top
I
top - podsumowanie pamieci
˛ wolnej i zużywanej przez procesy
Jesli Rss procesu ciagle
˛
rośnie -> przeciek pamieci
˛ (memory leak)!
GUT – Intel 2015/16
26/40
Narz˛edzie smem
Rok 2009 - dwie nowe metryki
I
Uss (unique set size) - ilość pamieci
˛ zwiazanej
˛
z pamieci
˛ a˛
fizyczna,
˛ unikalna dla procesu; ilość pamieci,
˛ ktora sie˛ zwolni po
zakończeniu działania procesu
I
Pss (propotional set size) - dzieli sume˛ obszarów pamieci
˛
współdzielonej, zwiazanych
˛
z pamieci
˛ a˛ fizyczna,
˛ na liczbe˛
procesów mapujacych
˛
te obszary;
GUT – Intel 2015/16
27/40
Narz˛edzie smem
Informacja dostepna
˛
w /proc/<PID>/smaps
GUT – Intel 2015/16
28/40
Narz˛edzie smem
smem - narz˛edzie zbierajace
˛ dane z plików smaps
I
I
Strona projektu: https://www.selenic.com/smem.
Napisane w Python-ie, instalacja w systemie wbudowanym
wymaga obecności środowiska Python, co może być problemem
smemcap - program zbierajacy
˛ informacje z plików smaps i
zapisujacy
˛ je w formie archiwum TAR, które moga˛ być nastepnie
˛
analizowane na komputerze hosta
GUT – Intel 2015/16
29/40
Narz˛edzie smem
GUT – Intel 2015/16
30/40
Narz˛edzie smem
GUT – Intel 2015/16
31/40
Narz˛edzie smem
GUT – Intel 2015/16
32/40
Wykrywanie przecieków pamieci
˛
I
Przeciek pamieci
˛ (memory leak) - pamieć
˛ jest alokowana, ale
nie jest zwalniana, kiedy przestaje być używana
I
W systemach wbudowanych:
I
I
I
urzadzenia
˛
maja˛ mało pamieci
˛
urzadzenia
˛
działaja˛ długo bez ponownego uruchomienia
Narz˛edzia do wykrywania przecieków: mtrace i Valgrind.
GUT – Intel 2015/16
33/40
Wykrywanie przecieków pamieci
˛ - mtrace
I
mtrace - komponent glibc śledzacy
˛ wywołania malloc(3),
free(3) i pokrewnych funkcji
Wywołanie mtrace() w programie rozpocz˛ecie śledzenia (mtrace-example.c)
Runtime: przypisanie log-a do zmiennej
środowiskowej MALLOC_TRACE
I komenda mtrace do odczytu log-a
I informacja o przecieku - po
zakończeniu programu
GUT – Intel 2015/16
34/40
Wykrywanie przecieków pamieci
˛ - Valgrind
I
Valgrind - narz˛edzie do identyfikacji problemów z pamieci
˛ a˛
I
I
I
nie trzeba re-kompilować sprawdzanych programu i bibliotek, ale
warto kompilować z opcja˛ -g (symbole debuggera)
uruchamia program w środowisku emulowanym
wada: program działa z obniżona˛ wydajnościa˛ (słaba możliwość
testowania programów działajacych
˛
w czasie rzeczywistym)
GUT – Intel 2015/16
35/40
Wykrywanie przecieków pamieci
˛ - Valgrind
I
Narz˛edzia diagnostyczne Valgrind:
I
I
I
I
I
I
memcheck: domyślne narz˛edzie, wykrywa przecieki pamieci
˛
cachegrind: zwraca liczbe˛ odwołań do pamieci
˛ cache procesora
(cache hit rate)
callgrind: zwraca koszt wywołań funkcji
helgrind: wskazuje na niepoprawne użycie Pthread API,
potencjalne zakleszczenia, wystapienia
˛
wyścigu
DRD: inne narz˛edzie analizy użycia Pthread API
massif: użycie stosu i sterty
I
Wybór narz˛edzia: opcja -tool
I
Dostepne
˛
jako pakiet zarówno dla Yocto Project jak i Buildroot
GUT – Intel 2015/16
36/40
Wykrywanie przecieków pamieci
˛ - Valgrind
Wykrywanie przecieków - narz˛edzie memcheck z opcja˛
–leakcheck=full (drukuje linie gdzie wykryto przeciek)
GUT – Intel 2015/16
37/40
Wykrywanie przecieków pamieci
˛ - Valgrind
Wykrywanie przecieków - narz˛edzie memcheck z opcja˛
–leakcheck=full (drukuje linie gdzie wykryto przeciek)
GUT – Intel 2015/16
38/40
Brak pamieci
˛
I
Standardowy mechanizm alokacji pamieci
˛ to “over-commit” jadro
˛
pozwala na alokacje˛ pamieci
˛ dla aplikacji bez sprawdzania,
czy dostepna
˛
jest pamieć
˛ fizyczna
I
Out of Memory (OOM): gdy cała pamieć
˛ wirtualna została
przydzielona.
I
I
I
System operacyjny próbuje odzyskać pamieć
˛ i wyjść ze stanu
OOM wywołujac
˛ nisokopriorytetowy proces OOM Killer (zabija
procesy, aż problem zniknie).
Działajace
˛ procesy, które napotykaja˛ sie˛ na stan OOM, próbujac
˛
zarezerwować pamieć,
˛ używajac
˛ funkcji malloc(), napotykaja˛ bład.
˛
Dobrze napisane programy powinny być przygotowane na taka˛
sytuacje.
˛
Oblicza “badness score” pomiedzy
˛
0 i 1,000 dla każdego procesu i
zamyka ten z najwyższym wynikiem
GUT – Intel 2015/16
39/40
Brak pamieci
˛
Zmiana parametru sposobu alokacji pamieci
˛ przez jadro:
˛
/proc/sys/vm/overcommit_memory:
I
Option 0: heuristic over-commit (this is the default)
I
Option 1 (always over-commit, never check)
I
I
I
przydatne tylko gdy program pracuje z dużymi, rzadkimi tablicami i
alokuje duże obszary pamieci,
˛ ale zapisuje tylko mała˛ cz˛eść tego
obszaru
rzadko spotykane w systemach wbudowanych
Option 2 (always check, never over-commit)
I
I
I
systemy czasu rzeczywistego, apliacje “safety-critical”
nie udaje sie˛ alokacja obszaru wiekszego,
˛
niż dopuszczalny limit,
który wynosi:
limit = sizeof(swap)+(total memory)*over-commit ratio
over-commit ratio jest kontrolowane przez
/proc/sys/vm/overcommit_ratio (domyślnie 50%)
GUT – Intel 2015/16
40/40

Podobne dokumenty