3 poin oleh GN⁺ 2025-11-05 | Belum ada 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

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

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
  • 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
  • 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

Belum ada komentar.

Belum ada komentar.