Nel kernel linux, ho scritto codice che assomiglia a copy_page_range
(mm/memoria.c) in modo da copiare la memoria da un processo a un altro con l'ottimizzazione COW. Gli indirizzi di destinazione e di origine possono essere compensati da PAGE_SIZE
e la COW funziona ancora. Ho notato, tuttavia, che in un programma utente quando copio dallo stesso indirizzo sorgente a diversi indirizzi di destinazione, il TLB non sembra essere stato scaricato correttamente. Ad alto livello, il mio codice livello utente esegue le seguenti operazioni (copio esattamente una pagina, 0x1000 byte sulla mia macchina, alla volta):Kernel Linux Invalidazione voci TLB
SRC = 0x20000000
- Scrivi SRC (chiamare il associato pagina
page1
). - Syscall per copiare SRC in 0x30000000 nel processo di destinazione. Ora, l'indirizzo di processo src 0x20000000 e l'indirizzo del processo di destinazione 0x30000000 puntano alla stessa pagina (
page1
). - Scrivere qualcosa di diverso da SRC (questo dovrebbe attivare un errore di pagina per gestire la COW). Si supponga che l'indirizzo di origine ora punti a
page2
. - Syscall per copiare SRC in 0x30001000 nel processo di destinazione.
A questo punto, dovrebbero esistere due pagine separate: SRC 0x20000000 page2
DST 0x30000000 page1
DST 0x30001000 page2
trovo che al punto 3, quando scrivo qualcosa di diverso in src 0x20000000, nessuna pagina errore è generato. Al momento dell'ispezione, le mappature di pagina reali sono: SRC 0x20000000 page1
DST 0x30000000 page1
DST 0x30001000 page1
Nel mio codice, se chiamo flush_tlb_page
e passare l'indirizzo di origine, il codice utente funziona come previsto con le mappature di pagina corretta . Quindi sono convinto di non mantenere correttamente il TLB. In copy_page_range
, il kernel chiama mmu_notifier_invalidate_range_start/end
prima e dopo altera le tabelle di pagina. Sto facendo esattamente la stessa cosa e ho ricontrollato che sto davvero passando la struct_mm e gli indirizzi corretti a mmu_notifier_invalidate_range_start/end
. Questa funzione non gestisce lo svuotamento del tlb?
Ok, così letteralmente come ho finito scrivendo questo, ho controllato dup_mmap
e si rese conto che il chiamante primario di copy_page_range
, dup_mmap
(kernel/fork.c), chiama flush_tlb_mm
. Sto indovinando che dovrei chiamare flush_cache_range
e flush_tlb_range
prima e dopo il mio codice del kernel. È corretto? Che cosa fa esattamente mmu_notifier_invalidate_range_start/end
?
puoi spiegare un po 'su mmu_notifiers? Sono bloccato sul fatto che questi hook siano usati solo dal kernel per informare kvm/vmm o viceversa è anche vero? se questi hook vengono utilizzati per tutte le pagine o solo per quelle pagine che vengono utilizzate da VMM. se sì, come sono registrati? – shami