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ę