#codziennylinustorvalds 23/32…

#codziennylinustorvalds 23/32 – special edition

Controlling a laser with Linux is crazy, but everyone in this room is crazy in his own way. So if you want to use Linux to control an industrial welding laser, I have no problem with your using PREEMPT_RT.
Kernel Summit 2006

Pewnie zastanawiacie się co jest takirgo niezwykłego w tym cytacie, że akurat o nim się bardziej rozpiszę.
W sumie to nic, natomiast PREEMPT_RT to niezwykle interesująca sprawa. Dlaczego akurat teraz o tym piszę?
Ano z powodu tego commita, który został wciągnięty przez Linusa kilka dni temu:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=70e6e1b971e46f5c1c2d72217ba62401a2edc22b
Co w tym commicie jest niezwykłego? Z technicznego punku widzenia niewiele – nowa opcja w configu będąca na chwilę obecną placeholderem. Natomiast z 'mentalnego’ punktu widzenia jest to ważny commit – patch PREEMPT_RT jest oficjalnie na ostatniej prostej do zmergowania do mainline kernela.

Dobra, to czym jest ten cały PREEMPT_RT? Jest to projekt rozwijany od 15 lat poza główną gałęzią kodu mający na celu zrobienie z Linuksa systemu czasu rzeczywistego. Jeśli ktoś nie wie co to system czasu rzeczywistego to już wyjaśniam – tak z grubsza jest to system w którym poprawność wyniku zależy od czasu wykonania, nieprzekraczającego pewnej górnej granicy.

Weźmy przykładowo wspomniany laser przemysłowy – tutaj nie liczy się tylko to czy ramię robota zostanie skierowane w dobrym kierunku, liczy się też czas w jakim to się stanie – kilka milisekund losowego opóżnienia i ktoś może mieć obicęte nogi przy samej dupie 😉

Co w tym takiego emocjonującego? A to, że uzyskanie przewidywalnego niskiego opóżnienia w systemie operacyjnym generalnego przeznaczenia to bardzo trudna sztuka. Oczywiście istnieją wyspecjalizowane systemy czasu rzeczywistego projektowane specjalnie do tego celu, natomiast mają one ograniczoną funkcjonalność w porównaniu do Linuksa.
Innym podejściem do tematu próbującym połączyć funkcjonalność Linuksa z wymaganiami czasu rzeczywistego jest zastosowanie podwójnego kernela. Projektem implementującym RT w ten sposób jest Xenomai – w systemie oprócz kernela Linuksa działa również mikrokernel o większym priorytecie, który obsługuje zadania czasu rzeczywistego.
Natomiast PREEMPT_RT podchodzi do problemu w inny sposób – zamienia on niektóre mechanizmy jądra na bardziej przyjazne dla RT.

Żeby jakoś nakreślć o co mniej więcej chodzi musimy sobie powiedziec coś o wywłaszczaniu(preemption) czyli przerwaniu działania bieżącego procesu na rzecz innego.
Dla niektórych będzie to zaskoczeniem – Linux nie pozwala na wywłaszczanie w całkowicie dowolnym momencie.
W przypadku gdy wykonywany jest kod aplikacji rzeczywiście może mieć miejsce w dowolnym punkcie, natomiast gdy jesteśmy w kodzie kernela(obsługa syscalla, przerwania itd) nie jest to takie proste.
Przy kompilacji mamy do wyboru kilka możliwych modeli wywłaszczania:
– CONFIG_PREEMPT_NONE – brak wywłaszczania, w tym trybie nie jest możliwe wywłaszczenie żadnego kodu kernela. Największa przepustowość, najwyższe opóżnienia. Tradycyjny uniksowy model.
– CONFIG_PREEMPT_VOLUNTARY – możliwe jest wywałaszenie w kernelu ale w ściśle określonych punktach. Mniejsze opóźnienia, mniejsza przepustowość. Obecnie najszerzej stosowany model.
– CONFIG_PREEMPT – możliwe jest wywałaszczanie w kernela w prawie niemal dowolnym momencie, oprócz sekcji krytycznych czyli spinlocków i kodu osługującego przerwania. Niskie opóznienia, zmniejszona przepustowość systemu.
Niektóre dystrybucje dostarczają kernel skompilowany w ten sposób, szukajcie pod 'low latency kernel.

Patch RT dodaje wprowadza dodatkową opcję CONFIG_PREEMPT_RT_FULL która między innymi:
– zamienia spinlocki na mutexy, więc możliwe jest wywłaszczenie takiego kodu
– zamienia interrupt handlery w wątki jądra, które można wywłaszczyć
– wprowadza dziedziczenie priorytetów dla semaforów i spinlocków aby zapobiec inwersji priorytetów

Dzięki powyższym(i nie tylko) modyfikacjom mało gdzie nie można wywłaszczyć kernela dzięki czemu możliwe jest uzyskanie ekstremalnie niskiego i przewidywalnego opóźnienia ale jak się domyślacie jest to kosztem przepustowości systemu.

Panie yuim, co mi p!@#$%sz o jakiś laserach, na ch!@# mi laser w moim Nginx?
Pomimo tego, że PREEMPT_RT jest bardzo niszową działką to warto o nim wspomnieć ponieważ przez 15 lat rozwoju tego projektu masa poprawek została wprowadzona do głównej gałęzi kernela.
Między innymi świetne narzędzie jakim jest ftrace oraz infrastruktura timerów o wysokiej rozdzielczości powstały jako część tego projektu. Dodatkowo dzięki RT kernelowi wykryto wiele bugów spowodowanych nieprawidłowym używaniem locków, które ciężko wykryć na normalnym kernelu. Ostatnią grubszą rzeczą z której wszyscy skorzystamy przed zmergowaniem do mainline jest reimplementacja printk()(tak, głupiego printk, to nie jest wcale trywialna sprawa):
https://lwn.net/Articles/780556/

Przy dobrych wiatrach RT patch powinien być zmergowany praktycznie cały w kernelu v5.4.

https://wiki.linuxfoundation.org/realtime/rtl/blog#the_jury_has_spoken
https://lkml.org/lkml/2019/7/15/1386

#linux #programista15k #komputery #cytatywielkichludzi #cytaty #heheszki #programowanie

Powered by WPeMatico