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:


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