Page MenuHomeFreeBSD

Eliminate redundant KASSERT()s in vm_fault() and its helpers
ClosedPublic

Authored by alc on May 26 2018, 6:17 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sep 15 2024, 10:48 PM
Unknown Object (File)
Aug 20 2024, 6:30 AM
Unknown Object (File)
Aug 17 2024, 3:04 AM
Unknown Object (File)
Aug 17 2024, 2:18 AM
Unknown Object (File)
Aug 15 2024, 11:08 AM
Unknown Object (File)
Aug 4 2024, 4:08 AM
Unknown Object (File)
May 22 2024, 8:08 AM
Unknown Object (File)
May 22 2024, 12:13 AM
Subscribers

Details

Summary

Near the beginning of vm_fault_hold() we have

if (wired)
        fault_type = prot | (fault_type & VM_PROT_COPY);
else
        KASSERT((fault_flags & VM_FAULT_WIRE) == 0,
            ("!wired && VM_FAULT_WIRE"));

Therefore, I don't see the point of the KASSERT(wired, ...)s removed by this change. They are redundant except in the case that we have to repeat the map lookup, in which case wired may have hypothetically changed.

To be clear about my motivation, when I refactor the loop for enqueueing/wiring pages out of vm_fault_populate() into a helper function, I don't want to have to pass wired to it just for the KASSERT().

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

This revision is now accepted and ready to land.May 26 2018, 7:42 AM
vm/vm_fault.c
1251 ↗(On Diff #43034)

Hmm. Could another thread initiate a wiring operation while the thread that got us to this point had the map unlocked? Should we be repeating this check from earlier in vm_fault_hold()?

if (fs.entry->eflags & MAP_ENTRY_IN_TRANSITION &&
    fs.entry->wiring_thread != curthread) {
        ...
vm/vm_fault.c
1251 ↗(On Diff #43034)

I think you are right. We should do it in the if (!fs.lookup_still_valid) block.

But I start thinking that instead of MAP_ENTRY_IN_TRANSITION, vm_map_busy() and other mechanisms which try to avoid some parallelism with wiring, we should much simplify it and make it much more straightforward. I mean, lets add sx lock to them map, take it exclusive around wiring/unwiring, and shared around all other vm_map_XXX() top level entry points().

It may be too naive, because vm_fault() can be entered from some deep stack (vm_map_wire() is an example, but of course there the fault handler must avoid taking the sx at all), but other places like copyouts while owning vnode locks etc. Still, the generic idea is to avoid parallel wire and anything else.

vm/vm_fault.c
1251 ↗(On Diff #43034)

I'm going to commit this change as is and follow up on the MAP_ENTRY_IN_TRANSITION issue later.

This revision was automatically updated to reflect the committed changes.