Wątki jądra

Transkrypt

Wątki jądra
Wątki jądra
Maciej Szwaja
Czym są wątki jądra?
Lekkie procesy, działające asynchronicznie w
przestrzeni jądra (podobnie jak zwykłe wątki w
przestrzeni użytkownika), niezwiązane z
żadnym procesem użytkownika
Ich nazwy przedstawione są na liście procesów w
nawiasach kwadratowych
Rodzicem wszystkich wątków jądra jest kthreadd
- PID = 2
Jak stworzyć wątek jądra?
Musimy napisać funkcję, którą wątek jądra będzie
wykonywał. Funkcja ma sygnaturę:
i nt
t h r e a d _ f u n c t i o n (v o i d *d a t a );
Ponieważ funkcja jest wywoływana w kontekście
procesu, wolno jej spać, a także wywoływać
funkcje, które potencjalnie mogą blokować.
Jak stworzyć wątek jądra?
Inicjujemy wątek za pomocą:
st r uct t ask_st r uct
*k t h r e a d _ c r e a t e (i n t
(*t h r e a d f n )(v o i d *d a t a ), v o i d
*d a t a , c o n s t c h a r n a me f mt [ ] , . . . );
Podajemy zdeklarowaną wcześniej funkcję
wątku, wskaźnik do danych, jakie chcemy jej
przekazać, oraz nazwę nowo tworzonego wątku
Otrzymujemy uchwyt typu struct task_struct
Jak stworzyć wątek jądra?
Utworzony wątek należy następnie uruchomić za
pomocą wake_up_process()
Tworzenie i uruchomienie wątku w jednym kroku:
#d e f i n e k t h r e a d _ r u n (t h r e a d f n , d a t a ,
n a me f mt , . . . )
Jak zatrzymać wątek jądra?
Jeśli chcemy zatrzymać wątek wołamy:
i n t k t h r e a d _ s t o p (s t r u c t t a s k _ s t r u c t *k );
Wątek powinien co jakiś czas sprawdzać, czy nie
zażądano od niego zaprzestania pracy. Robi to
wywołując:
i nt
k t h r e a d _ s h o u l d _ s t o p (v o i d );
W przypadku zwrócenia prawdy, wątek powinien
zakończyć swoje działanie
Zastosowanie
kthreadd – wątek-matka, jego zadaniem jest
tworzenie nowych wątków jądra
Wiele sterowników tworzy wątki na swoje
potrzeby
Wątki jądra służą do implementacji mechanizmu
kolejkowania pracy (workqueues)
Zastosowanie - przykłady
ksoftirqd – demon szeregujący i uruchamiający
dolne połówki (bottom-halves) przerwań
programowych (software interrupts)
migration – wątek odpowiedzialny za
przenoszenie procesów między procesorami
pdflush – odpowiada za zrzucanie zabrudzonych
stron pamięci na dysk
kacpid - wątek obsługujący zdarzenia związane z
zarządzaniem poborem mocy
Zastosowanie - przykłady
scsi_eh_? - wątek obsługi błędów urządzeń SCSI
kjournald – wątek obsługujący dziennik systemów
plików np ext3
kswapd – demon odzyskujący pamięć
kondemand – wątek regulujący częstotliwość
taktowania procesora (p-state)
Zastosowanie - przykłady
kmpathd – wątek obsługujący wielościeżkowość
(multipathing) komunikacji między procesorem,
a urządzeniami zewnętrznymi
ksmd – wątek odpowiadający za działanie
dzielonej pamięci jądra (Kernel Shared
Memory) wykorzystywanej przez maszyny
wirtualne
krfcommd – wątek obsługujący komunikację
radiową (Radio Frequency Communication)
urządzeń Bluetooth
Zastosowanie - przykłady
khubd – wątek obsługujący zdarzenia na
koncentratorze USB
khelper – wątek pomagający w wywoływaniu
funkcji z przestrzeni użytkownika z poziomu
jądra
kpsmoused – wątek obsługujący zdarzenia
przychodzące z myszki
kblockd – wątek nadzorujący pracę urządzeń
blokowych
Workqueues
W wielu przypadkach (np. przy obsłudze
przerwań) nasz kod powinien oddać procesor
jak najszybciej.
Głównym zadaniem wtedy jest przygotowanie
jednostki pracy (work item), która de facto
obsługuje przerwanie.
Jednostkę pracy wstawia się do kolejki
(workqueue), a w odpowiednim, późniejszym
czasie jądro wykorzysta któryś z wątkówrobotników (kworker) do jej wykonania
Workqueues
Można użyć domyślnych kolejek, tworzonych
przez jądro dla każdego CPU, ale można też
stworzyć swoje własne – do dyspozycji jest
wiele flag, za pomocą których można sterować
ich zachowaniem
(Documentation/workqueue.txt)
Rodzaje kolejek
Ograniczone (bound) – wątki jądra starają się
szeregować pracę, jednocześnie
maksymalizując zrównoleglenie, dana kolejka
przypisana jest do procesora
Nieograniczone (unbound) – jednostki pracy
wybierane są do wykonania równocześnie,
kolejka nie jest przypisana do procesora –
użytkownik dba o rozsądne gospodarowanie
zasobami
Przykład
Mamy trzy jednostki pracy w0, w1 i w2
w0 używa procesora przez 5 ms, następnie
zasypia na 10 ms, później działa jeszcze przez
5 ms, po czym kończy działanie
w1 i w2 korzystają z procesora przez 5 ms,
następnie zasypiają na 10 ms, a następnie
kończą działanie
Jednostki pracy są szeregowane w ograniczonej
kolejce, o parametrze max_active >= 3
Przykład
Przebieg zdarzeń:
C zas
Z d a r z e n ie
0 ms
w 0 z a c z y n a p ra c ę
5 ms
w 0 z a s y p ia
5 ms
w 1 z a c z y n a p ra c ę
10 ms
w 1 z a s y p ia
10 ms
w 2 z a c z y n a p ra c ę
15 ms
w 2 z a s y p ia
15 ms
w 0 b u d z i s ię
20 m s
w 0 k o ńc z y d z ia ła n ie
20 m s
w 1 b u d z i s i ę i k o ńc z y d z ia ła n ie
25 m s
w 2 b u d z i s i ę i k o ńc z y d z ia ła n ie
Wątki jądra
Dziękuję za uwagę

Podobne dokumenty