If the fs->m page was found invalid on the object queue, PG_ZERO flag is stale. Track the source of the page in the new fault state variable new_alloc, and ignore PG_ZERO if the page did not came from the allocator. new_alloc tracking is not exact, but good enough for the purpose. vm_page.h: remove no longer defined (P) locking annotation
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
Before, the de facto synchronization protocol for this field was that flags are set and cleared only by the page allocator. Now the field can be modified while the page is allocated. On its own this is ok, but it's fragile.
What about making vm_page_alloc() handle VM_ALLOC_ZERO like vm_page_alloc_noobj() does? That is, move all zeroing into the allocator, and make the fault handler and other consumers (kmem_*, iommu_pgalloc()) use VM_ALLOC_ZERO instead of checking for PG_ZERO manually.
I think the only real complication from an implementation perspective is the maintenance of the v_ozfod counter...?
Completely rework the patch: instead of clearing PG_ZERO, track the page source in the fault state.
| sys/vm/vm_fault.c | ||
|---|---|---|
| 1224 ↗ | (On Diff #167250) | I would rather have a flag needs_zero or needs_fill, which is set to false in vm_fault_allocate() if PG_ZERO is set immediately after the allocation, and is true by default. That would be somewhat more clear IMO, it describes the intent. |