Menjelajahi Memori Proses di Linux dengan Ramah
(0xkato.xyz)- Menjelaskan struktur memori proses di Linux pada level cara kerjanya yang nyata, serta menguraikan hubungan antara ruang alamat virtual dan memori fisik langkah demi langkah
- Menjelaskan secara konkret bagaimana proses memiliki dan mengakses memori dengan berfokus pada mekanisme inti seperti page table, VMA, mmap, page fault, CoW
- Memperkenalkan cara mengamati status memori per proses melalui sistem berkas
/proc, serta peran alat diagnosis lanjutan sepertipagemapdankpageflags - Membahas optimasi performa dan teknik dirty tracking di ruang pengguna melalui fitur kernel modern seperti Transparent Huge Pages (THP), userfaultfd, dan PAGEMAP_SCAN
- Juga menjelaskan prinsip desain kernel terkait keamanan dan performa seperti PTI untuk mitigasi Meltdown, TLB flush, dan kebijakan W^X, sehingga memberi pemahaman menyeluruh tentang manajemen memori Linux
Struktur dasar memori proses
- Saat program dijalankan, seolah-olah ada memori besar yang berkesinambungan, tetapi sebenarnya kernel Linux menyusunnya secara dinamis per halaman
- CPU melihat page table untuk menerjemahkan alamat virtual menjadi frame fisik
- Jika tidak ada pemetaan, terjadi page fault, lalu kernel mengalokasikan halaman baru atau mengembalikan galat
- Jika RAM fisik tidak mencukupi, kernel memindahkan halaman yang tidak dipakai ke disk atau membuang halaman berkas untuk membuat ruang kosong
/procadalah sistem berkas virtual yang dibangun kernel di memori, yang mengekspos status proses dan kernel dalam bentuk berkas
Ruang alamat dan VMA
- Setiap proses memiliki satu objek ruang alamat, yang di dalamnya terdiri dari banyak VMA (Virtual Memory Area)
- VMA adalah rentang alamat berkesinambungan dengan izin yang sama (R/W/X) dan backend yang sama (memori anonim atau berkas)
- Page table adalah struktur yang dirujuk perangkat keras, dan menyimpan informasi pemetaan (PTE) antara halaman virtual dan halaman fisik
- Perubahan ruang alamat dilakukan melalui tiga system call
mmap: membuat area barumprotect: mengubah izinmunmap: menghapus pemetaan
- Halaman menggunakan satuan dasar 4KiB, dan beberapa sistem juga mendukung halaman besar 2MiB·1GiB
Melihat susunan memori lewat /proc/self/maps
- Dengan perintah
cat /proc/self/maps, kita bisa memeriksa peta memori proses- Kode/data/bss berkas eksekusi, heap, pemetaan anonim, shared library, stack, dan lainnya akan ditampilkan
- Area
[vdso]dan[vvar]adalah kode dan data untuk system call cepat yang dipetakan kernel
Cara kerja mmap
mmapbukan alokasi memori nyata, melainkan mencatat janji terhadap ruang alamat- Halaman baru dialokasikan saat pertama kali diakses
- Saat memetakan berkas,
offsetharus selaras dengan ukuran halaman, dan akses melewati akhir berkas akan memicuSIGBUS MAP_SHAREDlangsung tercermin ke berkas, sedangkanMAP_PRIVATEmembuat halaman independen melalui copy-on-write (CoW) saat ada penulisanMAP_FIXED_NOREPLACEmeningkatkan keamanan dengan gagal jika alamat yang diminta sudah dipetakan
Akses pertama dan page fault
- Saat akses pertama ke pemetaan baru, jika CPU tidak menemukan entri di page table, maka terjadi page fault
- Kernel memeriksa validitas alamat, izin akses, dan keberadaan area
- Jika pemetaan anonim, kernel mengalokasikan halaman baru yang diisi nol; jika pemetaan berkas, data dibaca dari page cache
- minor fault terjadi ketika data sudah ada di RAM, sedangkan major fault terjadi jika perlu I/O disk
- Stack dilindungi oleh guard page, sehingga akses terlalu ke bawah akan memicu
SIGSEGV
fork() dan Copy-on-Write pada MAP_PRIVATE
- Saat
fork, proses induk dan anak berbagi halaman fisik yang sama, dan semuanya ditandai hanya-baca- Hanya ketika ada penulisan, halaman baru disalin agar tetap independen
- Pemetaan berkas
MAP_PRIVATEbekerja dengan prinsip yang sama - Opsi terkait
vfork: berbagi ruang alamat dengan indukclone(CLONE_VM): membuat threadMADV_DONTFORK,MADV_WIPEONFORK: mengecualikan pemetaan dari proses anak atau menginisialisasikannya ke nol
Mengubah izin dan invalidasi TLB
- Saat izin halaman diubah dengan
mprotect, kernel melakukan pemecahan VMA dan modifikasi page table, lalu melakukan invalidasi TLB - Menurut kebijakan W^X, suatu halaman tidak boleh sekaligus dapat ditulis dan dieksekusi
- TLB (Translation Lookaside Buffer) adalah cache translasi alamat terbaru, dan invalidasinya dapat menimbulkan jeda singkat
Pengamatan detail melalui /proc
- Dengan
/proc/<pid>/maps,smaps, dansmaps_rollup, kita dapat memeriksa izin per area, RSS, serta penggunaan HugePage /proc/<pid>/pagemapmenyediakan status per halaman (ada/tidak, swap, PFN, dll.), tetapi PFN tidak dibuka untuk pengguna biasa/proc/kpagecountdan/proc/kpageflagsmenampilkan jumlah pemetaan per PFN dan atribut halaman (anonim, berkas, dirty, dll.)- Dengan
mincoredanSEEK_DATA/SEEK_HOLE, kita bisa mengidentifikasi area data/hole pada sparse file - Dengan menggabungkan
PAGEMAP_SCANdanuserfaultfd, dirty tracking di ruang pengguna dapat diimplementasikan
Transparent Huge Pages (THP) dan mTHP
- THP secara otomatis menggabungkan memori yang sering diakses menjadi halaman besar (misalnya 2MiB) untuk meningkatkan efisiensi TLB
- Thread
khugepagedmenggabungkan halaman yang berdekatan
- Thread
- mTHP mendukung halaman besar variabel (folio) dengan berbagai ukuran seperti 16KiB dan 64KiB
- Penggunaannya dapat diperiksa melalui
AnonHugePagesdanFilePmdMappeddi/proc/self/smaps - Pengaturan tingkat sistem dapat dikelola di
/sys/kernel/mm/transparent_hugepage/ - Kontrol per area dimungkinkan dengan
MADV_HUGEPAGEdanMADV_NOHUGEPAGE
Dirty tracking di ruang pengguna
- Dengan
userfaultfddanPAGEMAP_SCAN, kita bisa menyalin hanya halaman yang berubah- Kernel melakukan pemindaian dan proteksi tulis dalam satu operasi atomik
- Efisien untuk snapshot, live migration, dan sebagainya
Mekanisme TLB flush
- Pada x86, invalidasi TLB dilakukan dengan dua cara
INVLPG: invalidasi satu halaman- flush penuh dengan memuat ulang root page table
PCIDdanINVPCIDmengelola tag TLB per proses untuk mengurangi flush yang tidak perlutlb_single_page_flush_ceilingadalah ambang yang dipakai kernel untuk memilih antara flush per halaman atau flush penuh
Mitigasi Meltdown: Page Table Isolation (PTI)
- Meltdown adalah kerentanan di mana data kernel dapat terekspos lewat cache selama speculative execution
- Linux memisahkan ruang alamat pengguna dan kernel dengan PTI (Page Table Isolation)
- Saat masuk ke kernel,
CR3dialihkan agar memakai page table khusus kernel PCIDdigunakan untuk meminimalkan TLB flush
- Saat masuk ke kernel,
- Fitur ini aktif secara default, dan bisa dinonaktifkan dengan
nopti
Prosedur aman kernel saat mengubah pemetaan
- Urutan saat mengubah pemetaan
- Menangani aturan cache
- Memodifikasi page table
- Menginvalidasi TLB
- Pemetaan internal kernel (
vmap,vmalloc) juga melakukan sinkronisasi cache dan TLB sebelum/sesudah I/O - Pada beberapa arsitektur, setelah menyalin kode diperlukan flush instruction cache
Struktur stack dan pemanggilan di x86
- Pada mode 64-bit, register RIP, RSP, RBP digunakan, dan stack tumbuh ke bawah
- Menurut ABI System V AMD64, pengiriman argumen memakai RDI, RSI, RDX, RCX, R8, R9, sedangkan nilai balik memakai RAX
- Mode pengguna berjalan di ring 3, kernel di ring 0, dan system call serta interrupt berpindah melalui gate
Situasi galat dan diagnosis
mmap→EINVAL: galat penyelarasan offset berkasmmap→ENOMEM: ruang virtual tidak cukup atau dibatasi overcommit- Akses ke pemetaan berkas memicu
SIGBUS: akses melewati EOF mprotect(PROT_EXEC)→EACCES: mountnoexecatau kebijakan W^X- RSS meningkat setelah
fork(): penyalinan halaman akibat CoW - Menimpa pemetaan yang ada dengan
MAP_FIXED→ disarankan memakaiMAP_FIXED_NOREPLACE
Checklist praktis
- Mengamankan memori segera:
mmap+PROT_READ|PROT_WRITE+MAP_PRIVATE|MAP_ANONYMOUS - Saat menghasilkan kode: pertahankan W^X, gunakan
mprotect(PROT_READ|PROT_EXEC) - Saat memetakan berkas:
offsetharus selaras halaman, jangan akses melewati EOF - Jika page fault banyak: gunakan
MADV_WILLNEEDatau lakukan akses awal - Analisis penggunaan memori:
/proc/<pid>/smaps_rollup→/proc/<pid>/maps forkpada proses besar: pertimbangkan CoW, gunakanexecdi proses anak- Untuk lingkungan sensitif terhadap latensi: amati THP/mTHP,
mlock, dan perilaku TLB
1 komentar
Komentar Hacker News
Saya sangat menyukai tulisan penjelasan singkat seperti ini
Bahkan kalau isinya sudah saya ketahui, tetap membantu karena saya bisa memastikannya kembali sambil membaca
Kalau melihat frasa seperti “mmap, without the fog”, entah kenapa terasa seperti artikel yang ditulis bersama LLM, jadi bikin cemas dan kesal
Ditambah ada ungkapan aneh seperti “without the fog”, jadi memberi kesan seolah chatgpt ikut menulisnya
Melihat pembahasan tentang instruction pipelining, saya jadi ingin kembali ke masa arsitektur sederhana seperti 6502 dulu
Waktu itu semuanya bekerja “apa adanya”, tanpa pemetaan atau proxy yang rumit
Kalau ada interkoneksi yang cukup cepat, rasanya kita mungkin bisa memimpikan kesederhanaan seperti itu lagi
Tetapi kalau melihat masalah seperti Meltdown dan Spectre, jelas ada harga yang harus dibayar dari kompleksitas yang makin besar
Di titik sekarang, ketika hukum Moore mulai mencapai batasnya, saya jadi bertanya-tanya apakah trade-off kompleksitas seperti ini benar-benar yang terbaik
Saya tidak berpikir kesederhanaan selalu lebih baik
Situs webnya muncul sebagai diblokir karena domain berbahaya atau tidak aman
Kalau melihat hasil pemeriksaan VirusTotal, sepertinya tidak ada masalah
Saya penasaran apa maksudnya ketika dibilang laporan error itu cuma “noise”