mirror_zfs/module/os/freebsd/zfs
Mark Johnston b3427b18b1 zfs: Fix a deadlock between page busy and the teardown lock
When rolling back a dataset, ZFS has to purge file data resident in the
system page cache.  To do this, it loops over all vnodes for the
mountpoint and calls vn_pages_remove() to purge pages associated with
the vnode's VM object.  Each page is thus exclusively busied while the
dataset's teardown write lock is held.

When handling a page fault on a mapped ZFS file, FreeBSD's page fault
handler busies newly allocated pages and then uses VOP_GETPAGES to fill
them.  The ZFS getpages VOP acquires the teardown read lock with vnode
pages already busied.  This represents a lock order reversal which can
lead to deadlock.

To break the deadlock, observe that zfs_rezget() need only purge those
pages marked valid, and that pages busied by the page fault handler are,
by definition, invalid.  Furthermore, ZFS pages always transition from
invalid to valid with the teardown lock held, and ZFS never creates
partially valid pages.  Thus, zfs_rezget() can use the new
vn_pages_remove_valid() to skip over pages busied by the fault handler.

PR:		258208
Tested by:	pho
Reviewed by:	avg, sef, kib
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D32931

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ryan Moeller <freqlabs@FreeBSD.org>
Closes #12828
2022-03-04 15:37:41 -08:00
..
abd_os.c Really zero the zero page 2022-03-04 15:37:33 -08:00
arc_os.c Remove b_pabd/b_rabd allocation from arc_hdr_alloc() 2021-09-14 14:31:50 -07:00
crypto_os.c FreeBSD: Retry OCF ENOMEM errors. 2021-05-27 22:31:57 -07:00
dmu_os.c FreeBSD: Clean up ASSERT/VERIFY use in module 2021-09-14 12:02:23 -07:00
hkdf.c Add FreeBSD support to OpenZFS 2020-04-14 11:36:28 -07:00
kmod_core.c zfs: add missed dependency of zfs module on zlib 2021-09-14 14:30:39 -07:00
spa_os.c FreeBSD: Clean up ASSERT/VERIFY use in module 2021-09-14 12:02:23 -07:00
sysctl_os.c Restore FreeBSD sysctl processing for arc.min and arc.max 2021-09-14 14:31:01 -07:00
vdev_file.c module: zfs: fix unused, remove argsused 2022-02-16 17:58:56 -08:00
vdev_geom.c Update checkstyle workflow env to ubuntu-20.04 2021-12-08 13:27:56 -08:00
vdev_label_os.c FreeBSD: Clean up ASSERT/VERIFY use in module 2021-09-14 12:02:23 -07:00
zfs_acl.c Use fallthrough macro 2021-11-02 09:50:30 -07:00
zfs_ctldir.c FreeBSD: Provide correct file generation number 2022-02-03 15:28:01 -08:00
zfs_debug.c Annotated dprintf as printf-like 2021-06-24 13:12:36 -07:00
zfs_dir.c FreeBSD: Clean up ASSERT/VERIFY use in module 2021-09-14 12:02:23 -07:00
zfs_file_os.c FreeBSD: Catch up with recent VFS changes 2021-11-02 13:48:54 -07:00
zfs_ioctl_compat.c FreeBSD: Fix legacy compat for platform IOCs 2020-09-30 13:25:50 -07:00
zfs_ioctl_os.c libzfs: On FreeBSD, use MNT_NOWAIT with getfsstat 2021-06-09 13:05:34 -07:00
zfs_racct.c module: zfs: fix unused, remove argsused 2022-02-16 17:58:56 -08:00
zfs_vfsops.c FreeBSD: vfsops: use setgen for error case 2022-02-03 15:28:01 -08:00
zfs_vnops_os.c Add dataset_kstats_update.. to mmap read/write paths 2022-02-16 17:58:56 -08:00
zfs_znode.c zfs: Fix a deadlock between page busy and the teardown lock 2022-03-04 15:37:41 -08:00
zio_crypt.c module: zfs: fix unused, remove argsused 2022-02-16 17:58:56 -08:00
zvol_os.c FreeBSD: Fix zvol_cdev_open locking 2022-02-03 15:28:01 -08:00