Sebuah thread dapat mengakses alamat virtual yang valid lalu berhenti sebelum akses selesai karena page tersebut belum memiliki backing yang present. Pada range yang didaftarkan dengan UFFDIO_REGISTER_MODE_MISSING, Linux dapat melaporkan fault itu melalui userfaultfd alih-alih menyelesaikannya sepenuhnya di kernel. Manager di user space kemudian menentukan isi page yang menjadi terlihat sebelum akses yang tertahan dilanjutkan.
Mekanisme ini memindahkan kendali atas satu bagian penanganan page fault. Kernel tetap mendeteksi fault, memvalidasi virtual memory area, menahan eksekusi yang mengalami fault, dan memasang mapping melalui antarmuka UFFDIO_*. User space memperoleh kendali atas isi dan waktu resolusi untuk fault yang terdaftar.
Registrasi menentukan batas intersepsi
Objek userfaultfd tidak mengalihkan semua page fault dalam sebuah proses. Descriptor diinisialisasi dengan UFFDIO_API, kemudian virtual address range tertentu didaftarkan melalui UFFDIO_REGISTER.
Untuk intersepsi missing page, registrasi menyertakan UFFDIO_REGISTER_MODE_MISSING. Akses ke page yang belum tersedia di dalam range tersebut dapat menghasilkan pesan UFFD_EVENT_PAGEFAULT. Event membawa alamat fault serta flags yang menjelaskan properti seperti apakah akses tersebut berupa write.
Batas range bersifat penting. Alamat di luar region terdaftar mengikuti jalur fault virtual memory biasa. Page yang sudah populated di dalam range yang hanya terdaftar untuk missing fault juga berjalan tanpa notifikasi missing-page.
Mekanismenya bersifat selektif: registrasi menentukan mapping yang berpartisipasi, sedangkan mode menentukan kelas fault yang dialihkan.
Faulting thread menunggu resolusi page
Pada penanganan missing-page secara sinkron, notifikasi bukan sekadar observasi setelah kejadian. Faulting thread dihentikan sampai fault diselesaikan.
Manager dapat memantau descriptor dengan poll(), select(), atau epoll() ketika descriptor memakai operasi nonblocking. Pembacaan descriptor menghasilkan struct uffd_msg yang menjelaskan event tertunda.
Urutan state yang disederhanakan:
thread mengakses alamat terdaftar
|
page belum tersedia
|
kernel mengantrekan event
|
thread tetap tertahan
|
manager membaca alamat fault
|
manager menyelesaikan page
|
akses dapat berlanjutBatas blocking ini merupakan bagian utama kontrak API. Manager berada pada critical path untuk akses pertama ke missing page. Resolusi yang terlambat secara langsung menambah waktu tunggu faulting thread.
UFFDIO_COPY memublikasikan page lengkap
Untuk missing fault, UFFDIO_COPY dapat menyalin isi page dari source buffer di user space ke mapping yang mengalami fault. UFFDIO_ZEROPAGE dapat menyelesaikan missing fault yang didukung dengan page berisi nol.
Dokumentasi kernel menyatakan operasi resolusi tersebut atomik terhadap visibilitas page: accessor lain tidak melihat page yang baru terisi sebagian. Thread terus mengalami fault atau tetap tertahan sampai pemasangan page selesai.
Jaminan itu lebih sempit daripada atomicity transaksi untuk region memory yang lebih besar. Resolusi beberapa page membutuhkan beberapa operasi kecuali antarmuka lain memberikan jaminan yang lebih luas. Consumer dapat menemukan satu page yang sudah terselesaikan sementara page lain dalam objek tingkat aplikasi yang sama masih belum tersedia.
Page merupakan granularitas penting bagi kontrak resolusi missing fault.
Resolusi dan wakeup dapat dipisahkan
Jalur resolusi normal membangunkan thread yang menunggu pada range terkait. Operasi UFFDIO_* yang relevan juga menyediakan varian *_MODE_DONTWAKE ketika pemasangan page dan wakeup thread perlu memiliki waktu berbeda.
Pemisahan ini memungkinkan manager mengisi beberapa page atau mengoordinasikan state lain sebelum eksekusi yang tertahan boleh berlanjut. Konsekuensinya, ada kewajiban tambahan: page dapat sudah present sementara waiter tetap tidur jika manager sengaja menekan wakeup.
Perbedaan ini penting untuk analisis latency. Ketersediaan page dan state runnable pada thread dapat menjadi dua transisi terpisah di bawah kendali eksplisit manager.
Missing fault berbeda dari write-protect fault
userfaultfd mendukung beberapa mode registrasi dengan semantik berbeda. Missing mode menangani akses ketika page yang dibutuhkan belum tersedia. Write-protect mode, yang didaftarkan dengan UFFDIO_REGISTER_MODE_WP, melaporkan write ke page yang dilindungi melalui mekanisme write protection milik userfaultfd.
Write-protect fault diselesaikan dengan mengubah protection melalui UFFDIO_WRITEPROTECT, bukan dengan memasok page baru lewat UFFDIO_COPY. Page beserta isinya dapat sudah present.
Mode tersebut dapat digabungkan untuk tipe memory dan fitur kernel yang mendukungnya, tetapi keduanya mewakili transisi berbeda:
missing mode:
tidak ada page yang dapat dipakai -> page dipasok -> akses berlanjut
write-protect mode:
page present, write tertahan -> protection dibuka -> write berlanjutMenganggap keduanya sebagai notifikasi page generik menghilangkan perbedaan state yang menentukan operasi resolusi yang valid.
Negosiasi fitur merupakan bagian kontrak
UFFDIO_API adalah handshake, bukan sekadar panggilan inisialisasi. Operasi ini menetapkan versi API dan menegosiasikan feature bits yang didukung kernel yang sedang berjalan. Perilaku registrasi dan ioctl berikutnya bergantung pada capability set hasil negosiasi tersebut.
Dukungan juga berbeda menurut tipe memory dan versi kernel. Anonymous mapping, shmem, dan hugetlbfs tidak memiliki riwayat dukungan yang identik untuk missing, minor, dan write-protect mode.
Kode yang menganggap sebuah mode tersedia hanya karena header mendefinisikan constant terkait dapat gagal pada kernel lain. Runtime feature bitmap adalah batas capability yang relevan.
Di titik ini, jaminan arsitektural juga perlu dipisahkan dari asumsi deployment. Antarmuka menetapkan semantik untuk fitur yang berhasil dinegosiasikan; mesin tertentu dapat menyediakan hanya sebagian.
Kontrol akses membatasi intersepsi fault
Linux saat ini menyediakan lebih dari satu jalur untuk membuat objek userfaultfd. System call userfaultfd() mendukung UFFD_USER_MODE_ONLY, yang membatasi descriptor pada fault yang berasal dari user mode. Intersepsi yang lebih luas tunduk pada kontrol keamanan dan privilege kernel.
Linux juga mendukung pembuatan melalui /dev/userfaultfd pada sistem yang menyediakannya, dengan akses yang diatur melalui permission filesystem pada device tersebut.
Kontrol ini relevan karena intersepsi fault dapat memengaruhi kemajuan execution context lain dan populasi memory. Ketersediaan API tidak setara dengan kewenangan tanpa batas atas setiap sumber fault.
Kegagalan manager menjadi kegagalan akses memory
Memindahkan resolusi ke user space juga memindahkan dependency kegagalan ke user space. Jika manager macet ketika faulting thread menunggu, akses memory ikut macet. Jika lifecycle descriptor berakhir, range terdaftar dan pending event mengikuti aturan teardown userfaultfd milik kernel; tidak ada fallback pager tingkat aplikasi yang otomatis muncul.
Liveness karena itu menjadi properti desain manager. Sistem yang memakai userfaultfd untuk demand paging, migration, snapshot, atau memory tracking perlu memperhitungkan scheduling manager, pengurasan event, cancellation, perubahan address space, dan urutan shutdown.
API menyediakan batas fault yang terkontrol, tetapi tidak menggantikan kebutuhan untuk menetapkan perilaku saat komponen pengendali batas tersebut berhenti membuat progres.
User-space paging memindahkan policy, bukan kepemilikan MMU
userfaultfd tidak mengubah virtual memory menjadi API page table di user space tanpa mediasi. MMU tetap memicu fault, kernel tetap memiliki kendali atas update page table, dan operasi UFFDIO_* meminta perubahan yang dikelola kernel.
Perubahannya berada pada penempatan policy. Untuk kelas fault yang terdaftar, user space dapat memilih isi page, mengoordinasikan state eksternal, melacak write, atau menunda kelanjutan sebelum meminta kernel menyelesaikan transisi mapping.
Batas ini memungkinkan post-copy migration dan sistem memory demand-driven lain tanpa mengharuskan faulting thread menjalankan signal handler yang membangun ulang mapping secara langsung. Pada saat yang sama, latency dan correctness manager menjadi bagian dari jalur akses memory.
Model akhirnya memiliki batas yang tegas: registrasi memilih virtual range dan kelas fault, kernel melaporkan fault yang cocok, eksekusi terkait menunggu ketika mode membutuhkan penanganan sinkron, lalu manager di user space menyelesaikan fault melalui operasi kernel yang telah dinegosiasikan.