3 poin oleh GN⁺ 2025-11-05 | 1 komentar | Bagikan ke WhatsApp
  • 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 seperti pagemap dan kpageflags
  • 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
  • /proc adalah 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 baru
    • mprotect: mengubah izin
    • munmap: menghapus pemetaan
  • Halaman menggunakan satuan dasar 4KiB, dan beberapa sistem juga mendukung halaman besar 2MiB·1GiB
Iklan

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

  • mmap bukan alokasi memori nyata, melainkan mencatat janji terhadap ruang alamat
    • Halaman baru dialokasikan saat pertama kali diakses
  • Saat memetakan berkas, offset harus selaras dengan ukuran halaman, dan akses melewati akhir berkas akan memicu SIGBUS
  • MAP_SHARED langsung tercermin ke berkas, sedangkan MAP_PRIVATE membuat halaman independen melalui copy-on-write (CoW) saat ada penulisan
  • MAP_FIXED_NOREPLACE meningkatkan 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
Iklan

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_PRIVATE bekerja dengan prinsip yang sama
  • Opsi terkait
    • vfork: berbagi ruang alamat dengan induk
    • clone(CLONE_VM): membuat thread
    • MADV_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, dan smaps_rollup, kita dapat memeriksa izin per area, RSS, serta penggunaan HugePage
  • /proc/<pid>/pagemap menyediakan status per halaman (ada/tidak, swap, PFN, dll.), tetapi PFN tidak dibuka untuk pengguna biasa
  • /proc/kpagecount dan /proc/kpageflags menampilkan jumlah pemetaan per PFN dan atribut halaman (anonim, berkas, dirty, dll.)
  • Dengan mincore dan SEEK_DATA/SEEK_HOLE, kita bisa mengidentifikasi area data/hole pada sparse file
  • Dengan menggabungkan PAGEMAP_SCAN dan userfaultfd, 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 khugepaged menggabungkan halaman yang berdekatan
    Iklan
  • mTHP mendukung halaman besar variabel (folio) dengan berbagai ukuran seperti 16KiB dan 64KiB
  • Penggunaannya dapat diperiksa melalui AnonHugePages dan FilePmdMapped di /proc/self/smaps
  • Pengaturan tingkat sistem dapat dikelola di /sys/kernel/mm/transparent_hugepage/
  • Kontrol per area dimungkinkan dengan MADV_HUGEPAGE dan MADV_NOHUGEPAGE

Dirty tracking di ruang pengguna

  • Dengan userfaultfd dan PAGEMAP_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
  • PCID dan INVPCID mengelola tag TLB per proses untuk mengurangi flush yang tidak perlu
  • tlb_single_page_flush_ceiling adalah 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, CR3 dialihkan agar memakai page table khusus kernel
    • PCID digunakan untuk meminimalkan TLB flush
    Iklan
  • Fitur ini aktif secara default, dan bisa dinonaktifkan dengan nopti

Prosedur aman kernel saat mengubah pemetaan

  • Urutan saat mengubah pemetaan
    1. Menangani aturan cache
    2. Memodifikasi page table
    3. 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

  • mmapEINVAL: galat penyelarasan offset berkas
  • mmapENOMEM: ruang virtual tidak cukup atau dibatasi overcommit
  • Akses ke pemetaan berkas memicu SIGBUS: akses melewati EOF
  • mprotect(PROT_EXEC)EACCES: mount noexec atau kebijakan W^X
  • RSS meningkat setelah fork(): penyalinan halaman akibat CoW
  • Menimpa pemetaan yang ada dengan MAP_FIXED → disarankan memakai MAP_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: offset harus selaras halaman, jangan akses melewati EOF
  • Jika page fault banyak: gunakan MADV_WILLNEED atau lakukan akses awal
  • Analisis penggunaan memori: /proc/<pid>/smaps_rollup/proc/<pid>/maps
  • fork pada proses besar: pertimbangkan CoW, gunakan exec di proses anak
  • Untuk lingkungan sensitif terhadap latensi: amati THP/mTHP, mlock, dan perilaku TLB

1 komentar

 
GN⁺ 2025-11-05
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

    • Nada tulisannya terasa seperti saat meminta Gemini menjelaskan sesuatu dengan mudah
      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

    • Tentu saya mengakui bahwa ‘trik-trik (cheats)’ seperti ini memang berkontribusi pada peningkatan performa
      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
    • Sebenarnya yang dijelaskan artikel itu adalah konsep virtual memory, dan ini teknologi yang bahkan sudah ada sekitar 10 tahun sebelum 6502
    • Memang benar kompleksitasnya bertambah, tetapi hasil yang didapat juga banyak
      Saya tidak berpikir kesederhanaan selalu lebih baik
    • Tapi saya penasaran kenapa Anda merindukan kesederhanaan seperti itu
  • Situs webnya muncul sebagai diblokir karena domain berbahaya atau tidak aman

    • Mungkin Anda sedang memakai laptop kantor? Tim keamanan perusahaan bisa saja tidak memercayai domain .xyz
    • Kemungkinan perangkat lunak keamanannya yang salah bertindak
      Kalau melihat hasil pemeriksaan VirusTotal, sepertinya tidak ada masalah
    • Ini tampaknya hanya false alarm biasa
    • Saya jadi penasaran browser mana yang memblokirnya
    • Lucu juga lol
  • Saya penasaran apa maksudnya ketika dibilang laporan error itu cuma “noise”