En gren der siger, hvem der skrev den

En gren ved navn noref-filemap-read-with-llm dukkede op i Linus Torvalds’ eget kernetræ i den forgangne weekend. Den rummer otte patches, alle skrevet og indsendt af Torvalds den 9. og 10. oktober, oven på 7.3-rc6. Den sidste er en tom commit, der ikke bærer andet end forklaringen, og tæt på slutningen af den tekst, under overskriften “Tools”, står et afsnit, som få kerne-commits indeholder:

“Koden, testprogrammerne, gennemgangen bag listen ovenfor og det første udkast til denne tekst blev lavet med en LLM-baseret kodeassistent (Claude Code) under min ledelse. Målingerne blev kørt på min egen maskine.”

Phoronix, som fandt grenen, mens de ventede på 7.3-rc7, bemærkede, at Torvalds næsten aldrig har arbejdsgrene i sit hovedrepositorium. De otte commits findes ikke i master, og han har ikke sagt, om de skal med i sammenlægningsvinduet for 7.4.

En whiteboardtavle fuld af håndtegnede diagrammer på et kontor
Torvalds siger, at koden, testprogrammerne og gennemgangen blev lavet med en assistent under hans ledelse. Illustrationsbillede. Christina Morillo · pexels · Pexels License

Problemet er én cachelinje

Serien angriber et konkurrenceproblem, som Matthew Wilcox rejste i 2024 ud fra en kundes arbejdsbyrde. Når mange tråde læser små mængder fra den samme fil, tager og slipper hver læsning en reference på det folio, der holder siden, så hver af dem skriver den samme cachelinje i struct page to gange. På Torvalds’ bærbare — en i7-8565U med fire kerner og otte tråde — lægger otte tråde, der laver 16 byte store pread()-kald mod én enkelt side, 99,92 procent af alle load-HITM’er på netop den linje.

Hans løsning er slet ikke at tage referencen. Et folio, der fjernes fra sidecachen, går nu først tilbage til sideallokatoren efter en RCU-nådeperiode, hvilket betyder, at en side fundet under rcu_read_lock() stadig holder filens data, indtil låsen slippes. Læsningen kopierer så direkte ind i brugerbufferen med sidefejl slået fra: ingen reference, ingen mellembuffer på stakken, ingen kontrol efter kopieringen og ingen grænse for læsningens størrelse.

Tidligere forsøg, skriver Torvalds, kopierede uden reference til en stakbuffer og validerede bagefter, og “standsede ved det, validering ikke kan se”: frigivelse, genbrug og genindsættelse på samme indeks, migrering, og læsning af hukommelse, der slet ikke er sidecache, heriblandt secretmem, ikke-accepteret hukommelse og “eller endnu værre MMIO med uønskede læseeffekter”. At udskyde frigivelsen fjerner de tilfælde i stedet for at opdage dem.

Tre gange så mange læsninger, og 30.538 HITM’er ned til 101

Tallene i commit-beskeden stammer fra én maskine, med ext4 og med CPU-modforanstaltninger og CONFIG_HARDENED_USERCOPY slået fra. Med otte tråde, der læser 16 byte fra én side, klarer basiskernen 9,9 til 10,4 millioner læsninger i sekundet ved 2.937–2.975 kernecyklusser per læsning. Med serien klarer den 30 til 33 millioner ved 725–726 cyklusser. Fire tråde, én per kerne, går fra 8,9–11,6 millioner til 25–26 millioner. Load-HITM’er målt med perf c2c falder fra 30.538 til 101.

En stak harddiske på et skrivebord
Den konkurrence, serien retter sig mod, opstår, når mange tråde læser små mængder fra samme fil. Illustrationsbillede. Marta Branco · pexels · Pexels License

Prisen er hukommelse, der står i kø og venter på en nådeperiode, og det er den del, Torvalds kalder mindst løst. Wilcox’ indvending mod at udskyde frigivelsen, citeret i beskeden, var, at “det føles simpelthen for risikabelt at have så meget hukommelse ventende på at blive genbrugt”. Patch 7 og 8 findes for at holde det i skak: over 1.024 ventende sider på en CPU kalder et andet arbejdselement synchronize_rcu_expedited() og frigiver listen, hvilket med fire processer, der stanser huller, sker 4.600 gange i sekundet — noget funktionens egen dokumentation siger, man ikke skal gøre i en løkke. Torvalds flager det selv: “Findes der en måde at få en kort nådeperiode på uden dem?”

Hvad han siger, han ikke har testet

Beskeden slutter med en liste over, hvad serien ikke er kørt imod: hukommelsespres ud over et enkelt tilfælde i en virtuel maskine, lockdep, KASAN, en kerne bygget med clang, 32-bit, CONFIG_HARDENED_USERCOPY og “enhver anden maskine end denne”. Om ændringen i planlæggeren i patch 8 skriver han: “Jeg er ikke sikker på, at det er retningen; jeg vil hellere have, at den frigivende opgave gør noget synkront, der lader planlæggeren være i fred.”

Det er den del, der er værd at følge, mere end værktøjet. Torvalds har offentliggjort en ydelseskritisk hukommelseshåndteringsserie, tilskrevet koden en assistent, beholdt målingerne for sig selv og efterladt to åbne spørgsmål til vedligeholderne af undersystemerne. Om den overlever gennemgangen på mailinglisten er en anden prøve end, om den kørte hurtigt på hans bærbare.