Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Make kqueue event status for vnodes shareable, and for stack...
details: https://anonhg.NetBSD.org/src/rev/1463355532b8
branches: trunk
changeset: 368549:1463355532b8
user: thorpej <thorpej%NetBSD.org@localhost>
date: Mon Jul 18 04:30:30 2022 +0000
description:
Make kqueue event status for vnodes shareable, and for stacked file systems
like nullfs, make the upper vnode share that status with the lower vnode.
And, lo, NetBSD 9.99.99.
Fixes PR kern/56713.
diffstat:
sys/fs/union/union_subr.c | 8 +++--
sys/kern/vfs_vnode.c | 43 +++++++++++++++++++++++++----
sys/kern/vfs_vnops.c | 39 ++++++++++++++++++---------
sys/kern/vnode_if.sh | 6 ++--
sys/miscfs/genfs/layer_vfsops.c | 7 ++--
sys/sys/param.h | 4 +-
sys/sys/vnode.h | 24 +++++++++++++---
sys/sys/vnode_impl.h | 8 ++++-
tests/lib/libc/kevent_nullmnt/t_nullmnt.sh | 2 -
9 files changed, 102 insertions(+), 39 deletions(-)
diffs (truncated from 425 to 300 lines):
diff -r 1ecb463c9456 -r 1463355532b8 sys/fs/union/union_subr.c
--- a/sys/fs/union/union_subr.c Sun Jul 17 22:02:23 2022 +0000
+++ b/sys/fs/union/union_subr.c Mon Jul 18 04:30:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_subr.c,v 1.81 2022/03/19 13:53:32 hannken Exp $ */
+/* $NetBSD: union_subr.c,v 1.82 2022/07/18 04:30:30 thorpej Exp $ */
/*
* Copyright (c) 1994
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.81 2022/03/19 13:53:32 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.82 2022/07/18 04:30:30 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -232,10 +232,11 @@
unlock_ap.a_desc = VDESC(vop_unlock);
unlock_ap.a_vp = UNIONTOV(un);
genfs_unlock(&unlock_ap);
- /* Update union vnode interlock & vmobjlock. */
+ /* Update union vnode interlock, vmobjlock, & klist. */
vshareilock(UNIONTOV(un), uppervp);
rw_obj_hold(uppervp->v_uobj.vmobjlock);
uvm_obj_setlock(&UNIONTOV(un)->v_uobj, uppervp->v_uobj.vmobjlock);
+ vshareklist(UNIONTOV(un), uppervp);
mutex_exit(&un->un_lock);
if (ohash != nhash) {
LIST_INSERT_HEAD(&uhashtbl[nhash], un, un_cache);
@@ -577,6 +578,7 @@
vshareilock(vp, svp);
rw_obj_hold(svp->v_uobj.vmobjlock);
uvm_obj_setlock(&vp->v_uobj, svp->v_uobj.vmobjlock);
+ vshareklist(vp, svp);
/* detect the root vnode (and aliases) */
if ((un->un_uppervp == um->um_uppervp) &&
diff -r 1ecb463c9456 -r 1463355532b8 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c Sun Jul 17 22:02:23 2022 +0000
+++ b/sys/kern/vfs_vnode.c Mon Jul 18 04:30:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.143 2022/04/09 23:45:45 riastradh Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.144 2022/07/18 04:30:30 thorpej Exp $ */
/*-
* Copyright (c) 1997-2011, 2019, 2020 The NetBSD Foundation, Inc.
@@ -148,7 +148,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.143 2022/04/09 23:45:45 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.144 2022/07/18 04:30:30 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_pax.h"
@@ -457,7 +457,8 @@
vp->v_mount = mp;
vp->v_type = VBAD;
vp->v_interlock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
- klist_init(&vp->v_klist);
+ klist_init(&vip->vi_klist.vk_klist);
+ vp->v_klist = &vip->vi_klist;
vip->vi_state = VS_MARKER;
return vp;
@@ -475,7 +476,7 @@
KASSERT(vip->vi_state == VS_MARKER);
mutex_obj_free(vp->v_interlock);
uvm_obj_destroy(&vp->v_uobj, true);
- klist_fini(&vp->v_klist);
+ klist_fini(&vip->vi_klist.vk_klist);
pool_cache_put(vcache_pool, vip);
}
@@ -1391,7 +1392,8 @@
vp->v_interlock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
uvm_obj_init(&vp->v_uobj, &uvm_vnodeops, true, 1);
- klist_init(&vp->v_klist);
+ klist_init(&vip->vi_klist.vk_klist);
+ vp->v_klist = &vip->vi_klist;
cv_init(&vp->v_cv, "vnode");
cache_vnode_init(vp);
@@ -1453,7 +1455,9 @@
mutex_obj_free(vp->v_interlock);
rw_destroy(&vip->vi_lock);
uvm_obj_destroy(&vp->v_uobj, true);
- klist_fini(&vp->v_klist);
+ KASSERT(vp->v_klist == &vip->vi_klist ||
+ SLIST_EMPTY(&vip->vi_klist.vk_klist));
+ klist_fini(&vip->vi_klist.vk_klist);
cv_destroy(&vp->v_cv);
cache_vnode_fini(vp);
pool_cache_put(vcache_pool, vip);
@@ -1916,7 +1920,7 @@
* Don't check for interest in NOTE_REVOKE; it's always posted
* because it sets EV_EOF.
*/
- KNOTE(&vp->v_klist, NOTE_REVOKE);
+ KNOTE(&vp->v_klist->vk_klist, NOTE_REVOKE);
mutex_exit(vp->v_interlock);
/*
@@ -2095,3 +2099,28 @@
tvp->v_interlock = fvp->v_interlock;
mutex_obj_free(oldlock);
}
+
+void
+vshareklist(vnode_t *tvp, vnode_t *fvp)
+{
+ /*
+ * If two vnodes share klist state, they must also share
+ * an interlock.
+ */
+ KASSERT(tvp->v_interlock == fvp->v_interlock);
+
+ /*
+ * We make the following assumptions:
+ *
+ * ==> Some other synchronization is happening outside of
+ * our view to make this safe.
+ *
+ * ==> That the "to" vnode will have the necessary references
+ * on the "from" vnode so that the storage for the klist
+ * won't be yanked out from beneath us (the vnode_impl).
+ *
+ * ==> If "from" is also sharing, we then assume that "from"
+ * has the necessary references, and so on.
+ */
+ tvp->v_klist = fvp->v_klist;
+}
diff -r 1ecb463c9456 -r 1463355532b8 sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c Sun Jul 17 22:02:23 2022 +0000
+++ b/sys/kern/vfs_vnops.c Mon Jul 18 04:30:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnops.c,v 1.233 2022/07/06 13:52:24 riastradh Exp $ */
+/* $NetBSD: vfs_vnops.c,v 1.234 2022/07/18 04:30:30 thorpej Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.233 2022/07/06 13:52:24 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.234 2022/07/18 04:30:30 thorpej Exp $");
#include "veriexec.h"
@@ -79,7 +79,7 @@
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/namei.h>
-#include <sys/vnode.h>
+#include <sys/vnode_impl.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/poll.h>
@@ -1428,9 +1428,17 @@
void
vn_knote_attach(struct vnode *vp, struct knote *kn)
{
+ struct vnode_klist *vk = vp->v_klist;
long interest = 0;
/*
+ * In the case of layered / stacked file systems, knotes
+ * should only ever be associated with the base vnode.
+ */
+ KASSERT(kn->kn_hook == vp);
+ KASSERT(vp->v_klist == &VNODE_TO_VIMPL(vp)->vi_klist);
+
+ /*
* We maintain a bitmask of the kevents that there is interest in,
* to minimize the impact of having watchers. It's silly to have
* to traverse vn_klist every time a read or write happens simply
@@ -1439,18 +1447,23 @@
*/
mutex_enter(vp->v_interlock);
- SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext);
- SLIST_FOREACH(kn, &vp->v_klist, kn_selnext) {
+ SLIST_INSERT_HEAD(&vk->vk_klist, kn, kn_selnext);
+ SLIST_FOREACH(kn, &vk->vk_klist, kn_selnext) {
interest |= vn_knote_to_interest(kn);
}
- vp->v_klist_interest = interest;
+ vk->vk_interest = interest;
mutex_exit(vp->v_interlock);
}
void
vn_knote_detach(struct vnode *vp, struct knote *kn)
{
- int interest = 0;
+ struct vnode_klist *vk = vp->v_klist;
+ long interest = 0;
+
+ /* See above. */
+ KASSERT(kn->kn_hook == vp);
+ KASSERT(vp->v_klist == &VNODE_TO_VIMPL(vp)->vi_klist);
/*
* We special case removing the head of the list, because:
@@ -1464,16 +1477,16 @@
*/
mutex_enter(vp->v_interlock);
- if (__predict_true(kn == SLIST_FIRST(&vp->v_klist))) {
- SLIST_REMOVE_HEAD(&vp->v_klist, kn_selnext);
- SLIST_FOREACH(kn, &vp->v_klist, kn_selnext) {
+ if (__predict_true(kn == SLIST_FIRST(&vk->vk_klist))) {
+ SLIST_REMOVE_HEAD(&vk->vk_klist, kn_selnext);
+ SLIST_FOREACH(kn, &vk->vk_klist, kn_selnext) {
interest |= vn_knote_to_interest(kn);
}
- vp->v_klist_interest = interest;
+ vk->vk_interest = interest;
} else {
struct knote *thiskn, *nextkn, *prevkn = NULL;
- SLIST_FOREACH_SAFE(thiskn, &vp->v_klist, kn_selnext, nextkn) {
+ SLIST_FOREACH_SAFE(thiskn, &vk->vk_klist, kn_selnext, nextkn) {
if (thiskn == kn) {
KASSERT(kn != NULL);
KASSERT(prevkn != NULL);
@@ -1484,7 +1497,7 @@
prevkn = thiskn;
}
}
- vp->v_klist_interest = interest;
+ vk->vk_interest = interest;
}
mutex_exit(vp->v_interlock);
}
diff -r 1ecb463c9456 -r 1463355532b8 sys/kern/vnode_if.sh
--- a/sys/kern/vnode_if.sh Sun Jul 17 22:02:23 2022 +0000
+++ b/sys/kern/vnode_if.sh Mon Jul 18 04:30:30 2022 +0000
@@ -29,7 +29,7 @@
* SUCH DAMAGE.
*/
"
-SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.75 2022/05/03 13:54:18 hannken Exp $'
+SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.76 2022/07/18 04:30:30 thorpej Exp $'
# Script to produce VFS front-end sugar.
#
@@ -444,7 +444,7 @@
*/ \\
mutex_enter((thisvp)->v_interlock); \\
if (__predict_true((e) == 0)) { \\
- knote(&(thisvp)->v_klist, (n)); \\
+ knote(&(thisvp)->v_klist->vk_klist, (n)); \\
} \\
holdrelel((thisvp)); \\
mutex_exit((thisvp)->v_interlock); \\
@@ -557,7 +557,7 @@
* meaningless from the watcher's perspective. \\
*/ \\
if (__predict_true(thisvp->v_op != dead_vnodeop_p)) { \\
- knote(&thisvp->v_klist, \\
+ knote(&thisvp->v_klist->vk_klist, \\
((ap)->a_fflag & FWRITE) \\
? NOTE_CLOSE_WRITE : NOTE_CLOSE); \\
} \\
diff -r 1ecb463c9456 -r 1463355532b8 sys/miscfs/genfs/layer_vfsops.c
--- a/sys/miscfs/genfs/layer_vfsops.c Sun Jul 17 22:02:23 2022 +0000
+++ b/sys/miscfs/genfs/layer_vfsops.c Mon Jul 18 04:30:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: layer_vfsops.c,v 1.54 2020/02/23 15:46:41 ad Exp $ */
+/* $NetBSD: layer_vfsops.c,v 1.55 2022/07/18 04:30:30 thorpej Exp $ */
/*
* Copyright (c) 1999 National Aeronautics & Space Administration
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.54 2020/02/23 15:46:41 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: layer_vfsops.c,v 1.55 2022/07/18 04:30:30 thorpej Exp $");
#include <sys/param.h>
#include <sys/sysctl.h>
@@ -205,10 +205,11 @@
xp = kmem_alloc(lmp->layerm_size, KM_SLEEP);
- /* Share the interlock and vmobjlock with the lower node. */
+ /* Share the interlock, vmobjlock, and klist with the lower node. */
vshareilock(vp, lowervp);
rw_obj_hold(lowervp->v_uobj.vmobjlock);
uvm_obj_setlock(&vp->v_uobj, lowervp->v_uobj.vmobjlock);
+ vshareklist(vp, lowervp);
vp->v_tag = lmp->layerm_tag;
vp->v_type = lowervp->v_type;
Home |
Main Index |
Thread Index |
Old Index