En gren som sier hvem som skrev den

En gren som heter noref-filemap-read-with-llm dukket opp i Linus Torvalds eget kjernetre i helgen. Den inneholder åtte patcher, alle skrevet og sjekket inn av Torvalds 9. og 10. oktober, oppå 7.3-rc6. Den siste er en tom innsjekking som ikke bærer annet enn forklaringen, og nær slutten av den teksten, under overskriften “Tools”, står et avsnitt få kjerneinnsjekkinger inneholder:

“Koden, testprogrammene, gjennomgangen bak listen over og det første utkastet til denne teksten ble gjort med en LLM-basert kodeassistent (Claude Code) under min ledelse. Målingene ble kjørt på min egen maskin.”

Phoronix, som fant grenen mens de ventet på 7.3-rc7, påpekte at Torvalds nesten aldri har arbeidsgrener i hovedrepositoriet sitt. De åtte innsjekkingene finnes ikke i master, og han har ikke sagt om de skal inn i sammenslåingsvinduet for 7.4.

En whiteboardtavle full av håndtegnede diagrammer på et kontor
Torvalds sier koden, testprogrammene og gjennomgangen ble gjort med en assistent under hans ledelse. Illustrasjonsbilde. Christina Morillo · pexels · Pexels License

Problemet er én cache-linje

Serien angriper et konkurranseproblem Matthew Wilcox tok opp i 2024 ut fra en kundes arbeidslast. Når mange tråder leser små mengder fra samme fil, tar og slipper hver lesing en referanse på folioet som holder siden, slik at hver av dem skriver den samme cache-linjen i struct page to ganger. På Torvalds’ bærbare — en i7-8565U med fire kjerner og åtte tråder — legger åtte tråder som gjør 16 byte store pread()-kall mot én enkelt side 99,92 prosent av alle load-HITM-er på nettopp den linjen.

Løsningen hans er å ikke ta referansen i det hele tatt. Et folio som fjernes fra sidebufferet går nå tilbake til sideallokatoren først etter en RCU-nådeperiode, noe som betyr at en side funnet under rcu_read_lock() fortsatt holder filens data til låsen slippes. Lesingen kopierer så rett inn i brukerbufferet med sidefeil slått av: ingen referanse, ingen mellombuffer på stakken, ingen kontroll etter kopieringen og ingen grense for lesingens størrelse.

Tidligere forsøk, skriver Torvalds, kopierte uten referanse til et stakkbuffer og validerte etterpå, og “stoppet ved det valideringen ikke kan se”: frigjøring, gjenbruk og ny innsetting på samme indeks, migrering, og lesing av minne som ikke er sidebuffer i det hele tatt, deriblant secretmem, ikke-akseptert minne og “eller enda verre MMIO med uønskede leseeffekter”. Å utsette frigjøringen fjerner de tilfellene i stedet for å oppdage dem.

Tre ganger så mange lesinger, og 30 538 HITM-er ned til 101

Tallene i innsjekkingsmeldingen kommer fra én maskin, med ext4 og med CPU-mottiltak og CONFIG_HARDENED_USERCOPY slått av. Med åtte tråder som leser 16 byte fra én side klarer basiskjernen 9,9 til 10,4 millioner lesinger i sekundet ved 2 937–2 975 kjernesykluser per lesing. Med serien klarer den 30 til 33 millioner ved 725–726 sykluser. Fire tråder, én per kjerne, går fra 8,9–11,6 millioner til 25–26 millioner. Load-HITM-er målt med perf c2c faller fra 30 538 til 101.

En stabel harddisker på en pult
Konkurransen serien retter seg mot oppstår når mange tråder leser små mengder fra samme fil. Illustrasjonsbilde. Marta Branco · pexels · Pexels License

Prisen er minne som står i kø og venter på en nådeperiode, og det er den delen Torvalds kaller minst løst. Wilcox’ innvending mot å utsette frigjøringen, sitert i meldingen, var at “det føles rett og slett for risikabelt å ha så mye minne som venter på å bli gjenbrukt”. Patch 7 og 8 finnes for å holde det i sjakk: over 1 024 ventende sider på en CPU kaller et andre arbeidselement synchronize_rcu_expedited() og frigjør listen, noe som med fire prosesser som stanser hull skjer 4 600 ganger i sekundet — noe funksjonens egen dokumentasjon sier at man ikke skal gjøre i en løkke. Torvalds flagger det selv: “Finnes det en måte å få en kort nådeperiode på uten dem?”

Hva han sier han ikke har testet

Meldingen avsluttes med en liste over hva serien ikke er kjørt mot: minnepress utover ett enkelt tilfelle i en virtuell maskin, lockdep, KASAN, en kjerne bygget med clang, 32-bit, CONFIG_HARDENED_USERCOPY og “enhver annen maskin enn denne”. Om endringen i planleggeren i patch 8 skriver han: “Jeg er ikke sikker på at dette er retningen; jeg vil heller at oppgaven som frigjør gjør noe synkront som lar planleggeren være i fred.”

Det er den delen som er verdt å følge, mer enn verktøyet. Torvalds har publisert en ytelseskritisk minnehåndteringsserie, tilskrevet koden en assistent, beholdt målingene for seg selv og lagt igjen to åpne spørsmål til vedlikeholderne av delsystemene. Om den overlever gjennomgangen på e-postlisten er en annen prøve enn om den gikk fort på hans egen bærbare.