VM wiring fixed
Brian Fundakowski Feldman
green at FreeBSD.org
Wed Apr 28 17:08:18 PDT 2004
There are several severe wiring bugs in -CURRENT that I believe I have fixed.
Please test/review as appropriate if you're affected by any of them. This
is a superset of the previous patch which just mostly-fixed mlockall(2).
* MAP_FUTUREWIRE was not unset in vmspace_dofree(), causing the next process
to use that vmspace to wire all of its memory.
* kmem_*() calls either called vm_map_wire() or set MAP_ENTRY_NOFAULT, but
kmem_free() did not undo the vm_map_wire() calls.
* vm_fault_unlock() could not unwire pages that were not in the pmap already,
leaking them permanently.
* vm_map_{un,}wire() did not keep track of wirings as they should. User
wirings are separate from system wirings, and there can be exactly one.
There can be unlimited system wirings, but wired_count will remain at
zero for map entries that are allocated as MAP_ENTRY_NOFAULT.
* vslock()/vsunlock() did not both use VM_MAP_WIRE_SYSTEM as they must;
I believe this resulted in more wiring leaks.
* vm_map_delete() did not wait for all wirings (except one user wiring) to
drain, so vslock() guaranteed nothing.
* The condition in vm_fault() where all pages have been exhausted is easy to
deadlock, but was impossible to recover from. The OOM killer works only
when all memory has been used, not all wired memory. However, now it is
possible to kill offending processes with SIGKILL instead of the
vm_fault() in trap_pfault() looping forever.
* The init(8) program should really be using mlockall(2) so that it can kill
off processes hogging all the wired memory. However, I have not fixed this
because in such case, e.g. while I would like for Ctrl+Alt+Del to work,
init(8) may actually need to allocate and wire new pages itself to keep
running. I think a way to fix this is to conditionalize the
vm_page_count_severe() condition on p->p_pid != 1 so that just like the
REAL system processes, it can bring the page count lower than "severe".
I haven't tested it out on SMP yet, but on UP the latest changes don't seem
to have any negative effects. All wired memory leaks appear to be gone and
although init(8) probably can't do it, I can enter DDB and "kill 9 <wirehog>"
to take the machine out of an all-wired deadlock. See patch at URL:
<http://green.homeunix.org/~green/vm-wiring.patch>
Thanks!
--
Brian Fundakowski Feldman \'[ FreeBSD ]''''''''''\
<> green at FreeBSD.org \ The Power to Serve! \
Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\
More information about the freebsd-current
mailing list