Sebuah thread dapat mengakses alamat virtual yang valid lalu berhenti sebelum akses tersebut selesai karena komponen userspace lain diberi tanggung jawab untuk menyelesaikan page fault. Dengan Linux userfaultfd, rentang memori tertentu dapat mengubah fault menjadi pesan descriptor sementara thread yang mengalami fault tetap tertahan sampai operasi resolusi yang sesuai memungkinkan eksekusi berlanjut.
Mekanisme ini bukan pengganti subsistem virtual memory kernel. Kernel tetap mendeteksi fault, memvalidasi rentang yang terdaftar, menahan jalur eksekusi yang terdampak, dan menjalankan operasi page table yang diminta manager. Batas yang berbeda terletak pada partisipasi userspace dalam menentukan kapan dan dengan isi apa sebuah fault diselesaikan.
Registrasi menentukan fault yang melintasi batas
Objek userfaultfd dimulai sebagai file descriptor yang belum dikonfigurasi. UFFDIO_API menetapkan versi protokol dan menegosiasikan feature bit. Rentang memori kemudian didaftarkan melalui UFFDIO_REGISTER, dengan mode yang memilih kelas fault yang akan diterima userspace.
Missing mode melaporkan akses ketika alamat terdaftar tidak memiliki page yang memenuhi akses tersebut. Manager dapat menyelesaikan fault semacam ini dengan operasi seperti UFFDIO_COPY atau UFFDIO_ZEROPAGE, sesuai jenis memori dan capability yang dilaporkan untuk rentang itu.
Minor mode menangani state yang berbeda. Backing page sudah ada, tetapi page-table entry yang relevan belum tersedia. Untuk mapping shmem dan hugetlbfs yang didukung, manager dapat memperbarui isi backing melalui mapping lain bila diperlukan, lalu memakai UFFDIO_CONTINUE agar kernel memasang mapping.
Write-protect mode menambahkan batas lain. Page yang sudah present dapat diberi userfaultfd write protection; penulisan kemudian menghasilkan event page fault dengan flag write-protect. Menghapus proteksi melalui UFFDIO_WRITEPROTECT menyelesaikan jalur write yang tertahan.
Mode-mode tersebut bukan sekadar nama berbeda untuk satu fault generik. Masing-masing mewakili state memori yang berbeda dan memerlukan resolusi yang sesuai dengan modenya.
Descriptor membawa event, bukan isi memori
Manager menerima record uffd_msg dengan membaca userfaultfd. Record page fault memuat alamat dan flag yang menjelaskan properti seperti write access, write-protect state, atau minor-fault state ketika feature tersebut berlaku.
Descriptor dengan demikian memisahkan notifikasi dari isi page. Event missing-page tidak membawa page yang seharusnya muncul pada alamat fault. Manager harus memperoleh atau membentuk data itu dari sumber lain, lalu menjalankan ioctl yang meminta kernel menyelesaikan fault.
Pemisahan ini berlaku lintas process boundary. Userfaultfd dapat dikirim melalui Unix domain socket sehingga sebuah process manager dapat menangani memori terdaftar milik process lain. Descriptor memindahkan akses ke interface pengelolaan fault; descriptor tidak memindahkan address space target sebagai byte biasa yang dapat dibaca.
Resolusi fault atomik pada batas visibilitas page
UFFDIO_COPY memiliki semantik yang mencegah thread lain melihat destination page dalam kondisi baru terisi sebagian. Thread yang mencapai state belum terselesaikan tetap mengalami fault atau tertahan sampai operasi tersebut membentuk page.
Atomicity ini lebih sempit daripada transaction semantics untuk aplikasi di sekitarnya. Jika manager menyelesaikan beberapa page secara terpisah, userfaultfd tidak mengubah resolusi itu menjadi satu commit multi-page. Struktur data aplikasi yang melintasi beberapa page tetap dapat memerlukan synchronization dan consistency protocol sendiri.
Wakeup juga dapat dipisahkan dari beberapa operasi resolusi. Varian UFFDIO_*_MODE_DONTWAKE memungkinkan manager melakukan pekerjaan tanpa langsung membangunkan fault yang tertahan, kemudian diikuti operasi wake eksplisit. Pola ini memungkinkan batching pada keputusan visibilitas dan scheduling, tetapi juga menciptakan state ketika persiapan page selesai sementara thread terkait sengaja tetap tertidur.
Blocking membentuk dependency edge menuju manager
Fault handling sinkron membuat thread yang mengalami fault bergantung pada kemampuan manager untuk berjalan dan menyelesaikan event. Dependency tersebut dapat diamati meskipun akses memori asal terlihat seperti load atau store biasa pada source code.
Manager yang menunggu pekerjaan yang membutuhkan thread tertahan dapat membentuk siklus. Kernel tidak dapat menentukan jalan keluar pada level aplikasi dari dependency tersebut; kernel hanya melihat fault yang belum diselesaikan. Desain dengan mode sinkron perlu menjaga jalur resolusi tetap independen dari resource yang progress-nya bergantung pada thread yang mengalami fault.
Batas yang sama memengaruhi latency. Akses page kini dapat mencakup scheduling manager, pengambilan data page, pemanggilan resolution ioctl, dan wakeup eksekusi yang tertahan. API tidak menetapkan latency tetap. Storage, network, scheduler, serta perilaku manager tetap menjadi input yang spesifik terhadap deployment.
Perubahan address space merupakan event terpisah
Dalam pengelolaan non-cooperative, page fault bukan satu-satunya perubahan state yang relevan. Feature userfaultfd opsional dapat melaporkan operasi seperti fork, remap, dan removal event. Notifikasi tersebut memungkinkan manager eksternal melacak perubahan yang dapat membatalkan asumsi tentang alamat virtual terdaftar.
Event delivery tidak membuat state address space menjadi immutable. Manager perlu memperlakukan perubahan mapping sebagai bagian protokol dan menyinkronkan metadata internal dengan event yang diminta. Asosiasi cache antara alamat dan data page eksternal dapat menjadi stale jika process mengubah mapping.
Konsekuensinya, alamat saja bukan object identity yang bertahan permanen. Maknanya bergantung pada state address space dan konteks registrasi tertentu.
Menutup descriptor menghapus delegasi
Ketika descriptor terakhir yang merujuk objek userfaultfd ditutup, rentang terdaftar dilepas dari registrasi dan event yang belum dibaca dibuang. Lifetime descriptor dengan demikian menjadi bagian dari kontrak pengelolaan fault.
Hal tersebut tidak berarti penutupan descriptor menghancurkan mapping. Operasi itu menghapus registrasi userfaultfd dari rentang terkait. Memori tetap mengikuti aturan virtual memory normal yang berlaku setelah delegasi hilang.
Perbedaan ini penting pada ownership transfer. Duplikasi atau pengiriman descriptor dapat memperpanjang lifetime objek userfaultfd melampaui descriptor lokal milik satu manager. Cleanup perlu memperhitungkan seluruh reference, bukan menganggap satu close() pasti mengakhiri protokol.
Fault terdelegasi tetap merupakan interface kernel yang dinegosiasikan
Userfaultfd mengekspos kontrol page fault melalui interface berversi dengan feature negotiation, bukan janji universal bahwa setiap mode bekerja pada setiap mapping. Jenis memori dan operasi yang didukung berbeda menurut mode dan capability kernel, sehingga caller perlu memeriksa feature mask serta ioctl mask yang dikembalikan saat setup.
Kontrak yang dihasilkan cukup spesifik: fault tertentu dapat menjadi pesan, thread tertentu dapat tetap tertahan, dan userspace dapat meminta operasi kernel tertentu untuk menyelesaikan fault tersebut. Kernel tetap memiliki page table dan memvalidasi setiap operasi. Userspace memiliki external policy hanya di dalam capability yang berhasil dinegosiasikan.
Batas ini memungkinkan userfaultfd dipakai pada mekanisme seperti demand population, external memory manager, dan migration system. Mekanisme tersebut tidak membuat memory access menjadi asynchronous secara umum; ia membentuk protokol eksplisit pada titik fault terdaftar, dengan descriptor lifetime, progress manager, mapping state, dan dukungan kernel hasil negosiasi tetap menjadi bagian dari correctness.