Wywłaszczalne jądro (kernel preemption)
Kiedy potrzebna jest nam szybka reakcja na zdarzenie:
- systemy krytyczne fabryk, elektrowni itp.
- systemy przetwarzające dane multimedialne
- szybsza interakcja z użytkownikiem np. GUI
- zwiększone wykorzystanie urządzeń I/O
Linux <= 2.4
- wywłaszczanie procesów w trybie użytkownika po wystąpieniu zdarzenia (np. IRQ) oraz po upływie kwantu czasu
- klasy "realtime" schedulera: SCHED_FIFO i SCHED_RR
- uprzywilejowanie interaktywnych procesów
ale:
- długotrwałe operacje w trybie jądra uniemożliwiały przerwanie procesu
Co powoduje opóźnienia?
- Długotrwałe blokowanie przerwań
- Długotrwałe przebywanie poprzedniego procesu w trybie jądra
- Czas działania schedulera
Linux >= 2.6
W jądrze 2.6 istnieje mozliwość wywłaszczenia procesu działającego u trybie jądra, co dotąd nie było możliwe. Jest to przede wszystkim potrzebne zarówno dla aplikacji krytycznych, w których liczy się czas rekacji na zdarzenie, jak i GUI. Linux 2.6 nie jest systemem RTOS (Real Time OS) w pełni definicji tego systemu, ale gwarantuje, że prawie wszystkie operacje będą obsłużone w danym okresie czasu. Co prawda pozostają operacje, których nie można rozdzielić, jednak dla użytkownika opóźnienia z tego wynikające ją niezauważalne. W większości przypadków użytkownicy czują poprawę interakcyjności systemu.
Linux 2.6:
- pozwala wywłaszczać procesy pracujące w trybie jądra
- na ogół wiązało się to ze znacznym skomplikowaniem systemu, wprowadzeniem blokad i wydłużeniem kodu jądra, w Linuxie jest inaczej - blokowanie wywłaszczania zintegrowane ze spinlock'ami
- oryginalna implementacja: patche do Linuxa 2.4 od 2.5.4 włączone do oficjalnego jądra
- opcjonalne - można wyłączyć podczas kompilacji
Nowe zasady:
- każdy proces ma licznik zagnieżdżonych wywołań preempt_disable()
- preempt_disable() zwiększa licznik, a preempt_enable() go zmniejsza
- wywłaszczenie może nastąpić gdy preempt_count() == 0
- zmniejszamy rozmiar sekcji krytycznych
- zwiększamy liczbę wywołań schedule() w różnych miejscach w kodzie jądra
- zmieniono implementację spinlock'ów, możliwe jest wywłaszczenie procesu czekającego na spinlock'u
Czego nie da się wywłaszczyć:
- nie można wywłaszczać kodu pomiędzy preempt_disable() a preempt_enable()
- domyślnie ochronione przed wywłaszczaniem są handlery przerwań i sam scheduler
- nie jest wywłaszczany kod, który działa z zablokowanymi przerwaniami (tu trzeba uważać)
Literatura:
Autor: Mariusz Zawadzki, mz209441@zodiac.mimuw.edu.pl