On s Rustem v kernelu je hlavně problém, že Rust si ještě neřekl, jaký vlastně je jeho paměťový model vzhledem k věcem typu přeskládávání instrukcí a viditelnost téhož z jiných CPU (třeba rcu_dereference() a vlastně celé RCU), paralelní přístup k paměti ze strany CPU i periferií (různé ty kruhové buffery a mailboxy pro komunikaci s protistranou jako má třeba virtio), a tak podobně. A nejen že si neřekl, ale někteří propagátoři Rustu v kernelu vlastně ani nevědí, že toto je nějaký problém k řešení.
Víc než jste o tom kdy chtěli vědět lze najít například v blogu Paula McKenneyho, autora RCU:
https://paulmck.livejournal.com/tag/rust
2. 9. 2024, 10:27 editováno autorem komentáře
Opravil bych jen čas: tohle bude naprosto zásadní problém, pokud se má rust v jádrře opravdu nějak víc rozšířit. Zatím se spíš omezují na nějaké "leaf" drivery, takže na větší problémy tohoto typu ještě nenarazili a vystačí s jednoduchým modelem, že jakýkoli paralelní přístup je špatně a chytrý překladač se postará, abychom ho vyloučili. A nebo když už je potřeba pracovat s něčím, co používá RCU nebo jinou "lockless" synchronizaci, přistupuje se k tomu přes céčkové wrappery, čímž se to stane PNJ. (A všetečným otázkám, jak že pak rust vlastně zaručuje tu memory safety, se raději vyhneme.)
Jako jo, ale ten budoucí čas už je "fakt brzo" - v článku se zmiňuje Asahi Lina a driver pro applovskou GPU. To už víceméně je ten problém kruhových bufferů s přístupem "z obou stran north bridge". Částečně z toho lze udělat PNJ ještě tím, že se ty buffery dají do paměti GPU, která je přes něco jako MTRR v CPU nakonfigurovaná jako necachovatelná a bez write-combing, ale umístění v hlavní paměti se stejně časem nevyhnou.
Ona ta cachovatelnost je docela rozdil mezi platformama.. napr stridat ARM vs X86, tak si musite v driveru hodne ohlidat, ze chcete opravdu onen koherentni pool (necachovanou oblast). Na jedne z platforem ale bude fungovat i cachovana, protoze struktura caches je jina a dokud to nezkusite portovat jinam, tak nevidite, ze mate problem, protoze zdanlive vse funguje.
A nekde jde udelat cache flush, a nekde udelat nejde. Nekde flush znamena dropnout celou cache, nekde jen dotcene radky - tahle nekonzistentnost je nejvetsi pitomost prozatim v Linuxu, kdyz resite low level veci, ale oni na to nemaj konzistentni API.
Prakticky napr nas DMA driver pouziva oba typy alokaci - koherentni region (s marnym vykonem) obsahuje jen deskriptory ktere je nutno menit pri linkovani bufferu runtime, a obycejne alokace pro vsechny ostatni - staticky inicializovane a pozdeji nemenne deskriptory.
Ano, je tomu tak (a neni to specifikum sitoveho subsystemu, ackoliv ten bude nejvice pametove narocny kod v kernelu - jako parsovani/fw/routing)
Na SPARCu vyvola nezarovnany pristup vyjimku, kterou odchyti callback, ktery dekoduje instrukci, adresu, registr, smer, zarovna adresu, provede cteni, vypreparuje data nebo je naopak doplni, a v pripade zapisu zapise zpet zarovnany blok/y. A mozna inkrementuje pocitadlo volani :D
https://github.com/torvalds/linux/blob/master/arch/sparc/kernel/unaligned_64.c
To je podobny jako kdyz nemate FPU (nebo jinou instrukci), a snazite se to fejkovat v sw skrze invalid opcode handler :D
a neni to specifikum sitoveho subsystemu
Specifikum síťového subsystému bylo spíš v tom, že jeho dlouholetý jediný maintainer byl zároveň maintainerem architektury SPARC, takže na to byl přirozeně citlivý. A možná trochu i v tom, že potřeba poskládat hlavičky síťových protokolů, k použití packed struktury trochu svádí.