The locking order between map locks and page "busy" locks
is that the page "busy" lock comes first, but uvm_map_clean()
breaks this rule by holding a map locked (as reader) while
waiting for page "busy" locks.
If another thread is in the page-fault path holding a page
"busy" lock while waiting for the map lock (as a reader)
and at the same time a third thread is blocked waiting for
the map lock as a writer (which blocks the page-fault thread),
then these three threads will all deadlock with each other.
Fix this by marking the map "busy" (to block any modifications)
and unlocking the map lock before possibly waiting for any
page "busy" locks.
Martin Pieuchot reported that the same problem existed in OpenBSD
he applied this fix there after several people tested it.
fixes PR 56952
the swap/drum block device was never intended to allow user opens,
but when the internal VOP_OPEN() in uvm_swap_init() was added
back in rev 1.135, the d_open method was changed from always-fail
to always-succeed in order to allow the new initial internal open.
this had the side effect of incorrectly allowing user opens too.
fix this by replacing the swap_bdevsw d_open with one that succeeds
for the first call but fails for all subsequent calls.
Reported-by: syzbot+90a23d2f19e5a0a302b3@syzkaller.appspotmail.com
This can be included unconditionally, and db_active can then be
queried unconditionally; if DDB is not in the kernel, then db_active
is a constant zero. Reduces need for #include opt_ddb.h, #ifdef DDB.
NKMEMPAGES_MAX_UNLIMITED. we used to limit kva to 1/8 of physmem
but limiting to 1/4 should be enough, and 1/4 still gives the kernel
enough kva to map all of the RAM that KMSAN has not stolen.
Reported-by: syzbot+ca3710b4c40cdd61aa72@syzkaller.appspotmail.com
high enough to allow the kernel to map all of RAM into kmem,
so that free physical pages rather than kernel virtual space is
the limiting factor in allocating kernel memory. this gives ZFS
more flexibility in tuning how much memory to use for its ARC cache.
XXX Not sure this should be allowed at all, but this way we don't
change the semantics of the existing code which was written under
essentially the assumption of -fwrapv.
This is guaranteed by a test earlier; adding the assertion just makes
it clearer that it applies to the branch where we call fo_mmap -- no
functional change intended.