kernel - Fix deadlock assertion panic with mmap/read combos
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 19 Jan 2011 22:11:10 +0000 (14:11 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 19 Jan 2011 22:11:10 +0000 (14:11 -0800)
commit283b944850fbb3421a77ef06aa121d066f5c8cad
tree5aec1b7be98c0c102671582685f2d590caff63d0
parent8bd60bc26686ba32daa68a8196296ecbc2d048a3
kernel - Fix deadlock assertion panic with mmap/read combos

* Normally the uiomove() is called with the buffer locked.  When
  uiomove()ing into mmap'd memory this can cause a lock recursion and
  panic, or a deadlock.

* Fix the problem by adding bqhold() and bqdrop() and adjusting the use
  of the b_refs field to prevent the buffer from being invalidated,
  allowing VFS VOP_READ operations to release the buffer prior to the
  uiomove() into user memory.

* Adjust brelse() and getnewbuf() to do the right thing.  Note that there
  are two cases where b_refs can transition from 0->1.  The VFS
  release/uiomove case will only transition b_refs while the buffer is
  locked while findblk() will transition b_refs at any time (while holding
  the spin lock).  We only care about retaining the VM pages in the
  transition-during-locked case.

* Original problem reproducable with

  grep -r --mmap SomeString /usr/pkgsrc

Reported-by: YONETANI Tomokazu <qhwt.dfly@les.ath.cx>
sys/kern/vfs_bio.c
sys/sys/buf.h
sys/vfs/hammer/hammer_vnops.c