Wpis z mikrobloga

#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
y.....m - #codziennylinustorvalds 23/32 - special edition

Controlling a laser with ...

źródło: comment_MdNCrua57Wn38asJ1Sfj8Xha1hAvKPjM.jpg

Pobierz
  • 12
@Kryspin013: jeśli ktoś robi muzykę na linuksie i i ma podłączone instrumenty do komputera to wtedy ten low latency kernel ma sens. Nie przychodzą mi inne sesnowne zastosowania do głowy, muzycy byli jednymi z pierwszych testerów różnych patchy zmniejszajacych opoznienie.

Spodziewamy efekt na desktopie jest taki, że jak będziesz ruszał kursorem to nigdy nie zobaczysz laga natomiast będzie to kosztem przykładowo dłuższego kopiowania plików czy renderowania strony w przeglądarce. No i
via Wykop Mobilny (Android)
  • 5
@yuim:

To jeszcze jako bonus zagadka. Dlaczego nie można po prostu wywłaszczyć procesu który trzyma spinlock tylko RT patch robi jakieś kombinacje z zamianą ich na muteksy?


Bo może dojść do zakleszczenia gdy ni z gruchy ni z pietruchy wyskoczymy z sekcji krytycznej nie zwalniając spinlocka, kolejny fragment kodu(czy normalny, czy irq_handler) może wtedy czekać w nieskończoność na zdjęcie blokady.

Tu coś Pan Linus o tym pisze jak bezpiecznie używać spinlocków