Portál AbcLinuxu, 5. května 2025 23:16
No matter how hard I try
You keep pushing me aside
And I can't break through
There's no talking to you
It's so sad that you're leaving
It takes time to believe it
But after all is said and done
You're gonna be the lonely one
Velikost shluku 64 KB může dávat smysl v mnoha situacích; velikost shluku 1 MB může být správnou volbou pro souborový systém, na kterém budou samé velké soubory. Není třeba říkat, že vybráním velké velikosti shluku u souborového systému, kde převládají malé soubory, může vést ke značnému plýtvání místem.Dvě věci mě k tomuhle napadly - jednak jak se shluk bloků liší od extentů a druhak, co SSD, nepomůže jim takováto velikost shluku bloků blížící se velikosti erase blocku?
rmmod
modul odloaduje bez zjevné chyby, je všechno v pořádu, nemůžete zdaleka vždy spolehnout. V situaci, kdy se v driveru stane něco, s čím se nepočítalo, to platí dvojnásob.
No, když myslíte… Já už viděl pár bugů, které spočívaly právě v tom, že když všechno nešlo hladce, modul po sobě nedokázal čistě uklidit, což vedlo v lepším případě k různým oopsům, v horším až ke kernel panic.
Že si uživatelé myslí, že odloadování modulu je "běžný a spolehlivý způsob" řešení problémů, to samozřejmě vím (a také jsem si to dřív myslel). Na druhou stranu už jsem se několikrát setkal i s radikálním tvrzením "module unloading is an unsupported operation", a to od lidí, kteří toho o jádře a driverech vědí o hodně víc než já (a ti první). Podle toho, co jsem ve zdrojácích viděl, je pravda někde mezi, ale rozhodně už si nemyslím, že unload modulu, který se dostal do problémů, je dobrý nápad.
Network controller: Realtek Semiconductor Co., Ltd. RTL8191SEvB Wireless LAN Controller (rev 10)výrobce protlačil ovladač do jádra 3.0 a od té doby na něj ... V současné době, když se používá s WPA2 Entreprise a migruje z jedné AP na druhou, tak dokáže ztratit autentizaci takovým způsobem, že pomůže jen odstranění a načtení. Aby toho nebylo málo, tak je ovladač v takovém stavu, že dokáže zatuhnout jádro (ne panic) a protože mám šifrovaný komplet disk kromě bootu, tak ani kexec k odchycení chyby a reportu moc nepomůže. Většinou se to moc nestane, když bych byl zároveň přes kabel, takže ani po síti nic a vůbec kdo by se s tím s..l. Karta od jiného výrobce je už na cestě.
Samozřejmě se může stát, že to v konkrétním případě opravdu fungovat bude a zařízení se správně reinicializuje a bude zase fungovat. Jenže jednak to tak není zdaleka vždy, jednak i když to na první pohled vypadá, že všechno hladce funguje, problémy mohou nastat později. Setkal jsem se třeba s tím, že zákazník se pokoušel řešit problémy s USB zařízením tím, že odloadoval všechny moduly, které měly něco společného s USB. Na první pohled to sice pomohlo, ale pak systém zhavaroval při spuštění supportconfigu. Důvodem bylo to, že modul uhci_hcd
po sobě neuklidil slab cache (protože nebyla prázdná), pointer name
v příslušné struktuře odkazoval na řetězec v tom modulu, tj. do stránky, která už nebyla namapovaná. A podobných příkladů jsem už viděl víc.
V ideálním světě by mělo platit, že pokud se modul úspěšně odloaduje bez použití Síly, tak po sobě korektně uklidí je všechno v naprostém pořádku. V takovém světě ale bohužel nežijeme - a to se v této diskusi snažím vysvětlit.
Na výkonu se to dokáže projevit i v řádu procent
Dělal jste nějaké benchmarky nebo si to prostě jen myslíte?
protože všechny symboly se u monolitického jádra volají přímo a ne přes tabulky
Volání exportovaného symbolu z jiného modulu vypadá úplně stejně, ať je ten modul zakompilován přímo do jádra nebo je natažen pomocí insmod
/modprobe
. Takhle třeba vypadá disassemblovaná funkce nfnetlink_queue_fini()
z modulu nefnetlink_queue
, která volá nejdřív funkci remove_proc_entry
z fs/proc/generic.c
, která je přímo v image jádra, a potom netlink_unregister_notifier()
z modulu netlink
nataženého ručně pomocí modprobe
.
crash> dis nfnetlink_queue_fini 0xffffffffa0488548 <cleanup_module>: push %rsi 0xffffffffa0488549 <nfnetlink_queue_fini+1>: mov $0xffffffffa04892e0,%rdi 0xffffffffa0488550 <nfnetlink_queue_fini+8>: callq 0xffffffff814a9ac0 <nf_unregister_queue_handlers> 0xffffffffa0488555 <nfnetlink_queue_fini+13>: mov $0xffffffffa048a020,%rdi 0xffffffffa048855c <nfnetlink_queue_fini+20>: callq 0xffffffff8147bf20 <unregister_netdevice_notifier> 0xffffffffa0488561 <nfnetlink_queue_fini+25>: mov -0x1e4d2be8(%rip),%rsi # 0xffffffff81fb5980 0xffffffffa0488568 <nfnetlink_queue_fini+32>: mov $0xffffffffa048903f,%rdi 0xffffffffa048856f <nfnetlink_queue_fini+39>: callq 0xffffffff811b5860 <remove_proc_entry> 0xffffffffa0488574 <nfnetlink_queue_fini+44>: mov $0xffffffffa04891c0,%rdi 0xffffffffa048857b <nfnetlink_queue_fini+51>: callq 0xffffffffa043a3a0 <nfnetlink_subsys_unregister> 0xffffffffa0488580 <nfnetlink_queue_fini+56>: mov $0xffffffffa048a000,%rdi 0xffffffffa0488587 <nfnetlink_queue_fini+63>: callq 0xffffffff814a4490 <netlink_unregister_notifier> 0xffffffffa048858c <nfnetlink_queue_fini+68>: pop %rdi 0xffffffffa048858d <nfnetlink_queue_fini+69>: jmpq 0xffffffff810c9920 <rcu_barrier> crash> rd -8 0xffffffffa048856f 5 ffffffffa048856f: e8 ec d2 d2 e0 ..... crash> rd -8 0xffffffffa0488587 5 ffffffffa0488587: e8 04 bf 01 e1 .....
Ale i kdyby to tak nebylo, několik procent rozdílu byste z toho rozhodně nedostal. Jednak rozdíl mezi direct a indirect call není nějak propastný, jednak volání funkcí jiných modulů není až tak moc (a v časově kritickém kódu už vůbec ne), často navíc stejně probíhá přes nějakou tabulku typu foo_ops
.
Benchmarky přímo jádra jsem nedělal, ale mám zkušenosti s nepřímími voláními v C++ (virtuální funkce), kde to funguje podobně.
To není ani zdaleka podobné. Obdobou virtuálních funkcí z C++ jsou různé *_ops
struktury, u kterých je opět jedno, jestli je příslušný modul nalinkován přímo do image nebo ne.
To, co tam máte disassemblované, je načtený modul, ne? Ten volá všechno nepřímo.
Na tom vůbec nezáleží. Tady máte pro úplnost volání funkce strlen()
(přímo v image) z remove_proc_entry()
(přímo v image):
crash> dis remove_proc_entry ... 0xffffffff811b58ad <remove_proc_entry+77>: callq 0xffffffff812b9e40 <strlen> ... crash> rd -8 0xffffffff811b58ad 5 ffffffff811b58ad: e8 8e 45 10 00 ..E..
Vidíte tam nějaký rozdíl oproti tomu, co je nahoře? Podle mne je to naprosto stejná instrukce (call %rip+imm32
). Poslední možnost, tj. funkce z image volající funkci z nataženého modulu, nemá smysl řešit, protože to je v principu možné jen přes nějaký callback, takže tam to bude zase jedno.
Linuxová komunita si stále myslí, že vyvíjí pro servery a bude za chvíli počítat s terabajty paměti.
Jakou linuxovou komunitu to máte na mysli? Jestli vývojáře jádra, tak o těch to rozhodně neplatí. Jestli vývojáře desktopových aplikací, tak u těch by bylo při ceně kolem 1000 Kč za 8 GB předpoklad, že nemá smysl kvůli pár MB omezovat funkčnost nebo snižovat výkon, celkem oprávněný.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.