Bring back previous fix for UVM vnode deadlock.
authormpi <mpi@openbsd.org>
Thu, 4 Mar 2021 08:38:48 +0000 (08:38 +0000)
committermpi <mpi@openbsd.org>
Thu, 4 Mar 2021 08:38:48 +0000 (08:38 +0000)
commit00e7696ef29d639c47992c239d3900a5b4cbb811
treeaac02aee384aa490b925dab518d07a757f5e0e0b
parenta82f3303477b91caf3f740262c66693c42da315c
Bring back previous fix for UVM vnode deadlock.

tb@ reports that refaulting when there's contention on the vnode makes
firefox start very slowly on his machine.  To revisit when the fault
handler will be unlocked.

ok anton@

Original commit message:

Fix a deadlock between uvn_io() and uvn_flush(). While faulting on a
page backed by a vnode, uvn_io() will end up being called in order to
populate newly allocated pages using I/O on the backing vnode. Before
performing the I/O, newly allocated pages are flagged as busy by
uvn_get(), that is before uvn_io() tries to lock the vnode. Such pages
could then end up being flushed by uvn_flush() which already has
acquired the vnode lock. Since such pages are flagged as busy,
uvn_flush() will wait for them to be flagged as not busy. This will
never happens as uvn_io() cannot make progress until the vnode lock is
released.

Instead, grab the vnode lock before allocating and flagging pages as
busy in uvn_get(). This does extend the scope in uvn_get() in which the
vnode is locked but resolves the deadlock.

ok mpi@

Reported-by: syzbot+e63407b35dff08dbee02@syzkaller.appspotmail.com
sys/uvm/uvm_pager.h
sys/uvm/uvm_vnode.c
sys/uvm/uvm_vnode.h