git: 115479c27d2a - releng/13.1 - vfs: [2/2] fix stalls in vnode reclaim by only counting attempts
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 25 Mar 2022 14:04:15 UTC
The branch releng/13.1 has been updated by mjg:
URL: https://cgit.FreeBSD.org/src/commit/?id=115479c27d2a6bcb263ac8aab1c1eec4daa64eba
commit 115479c27d2a6bcb263ac8aab1c1eec4daa64eba
Author: Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-03-07 10:38:17 +0000
Commit: Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-03-25 14:04:00 +0000
vfs: [2/2] fix stalls in vnode reclaim by only counting attempts
... and ignoring if they succeded, which matches historical behavior.
Reported by: pho
Approved by: re (gjb)
(cherry picked from commit 3a4c5dab9266fac93a5cb22c7cee3938466aedea)
---
sys/kern/vfs_subr.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 5c5faf455f2b..d27e7a15d886 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1307,8 +1307,29 @@ vnlru_free_impl(int count, struct vfsops *mnt_op, struct vnode *mvp)
TAILQ_REMOVE(&vnode_list, mvp, v_vnodelist);
TAILQ_INSERT_AFTER(&vnode_list, vp, mvp, v_vnodelist);
mtx_unlock(&vnode_list_mtx);
- if (vtryrecycle(vp) == 0)
- count--;
+ /*
+ * FIXME: ignores the return value, meaning it may be nothing
+ * got recycled but it claims otherwise to the caller.
+ *
+ * Originally the value started being ignored in 2005 with
+ * 114a1006a8204aa156e1f9ad6476cdff89cada7f .
+ *
+ * Respecting the value can run into significant stalls if most
+ * vnodes belong to one file system and it has writes
+ * suspended. In presence of many threads and millions of
+ * vnodes they keep contending on the vnode_list_mtx lock only
+ * to find vnodes they can't recycle.
+ *
+ * The solution would be to pre-check if the vnode is likely to
+ * be recycle-able, but it needs to happen with the
+ * vnode_list_mtx lock held. This runs into a problem where
+ * VOP_GETWRITEMOUNT (currently needed to find out about if
+ * writes are frozen) can take locks which LOR against it.
+ *
+ * Check nullfs for one example (null_getwritemount).
+ */
+ vtryrecycle(vp);
+ count--;
mtx_lock(&vnode_list_mtx);
vp = mvp;
}