Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys In vcache_reclaim(), post NOTE_REVOKE immediately after ...
details: https://anonhg.NetBSD.org/src/rev/6a14e9f70fc3
branches: trunk
changeset: 368789:6a14e9f70fc3
user: thorpej <thorpej%NetBSD.org@localhost>
date: Fri Aug 05 05:20:39 2022 +0000
description:
In vcache_reclaim(), post NOTE_REVOKE immediately after changing the
vnode state to VS_RECLAIMING, before we actually call VOP_RECLAIM(),
which will release the reference on the lower node of a stacked FS
vnode, which is likely to free the upper node's v_klist backing store.
Acquire the vnode interlock when checking for kevent interest now,
because the vp->v_klist pointer is now volatile.
PR kern/56950
diffstat:
sys/kern/vfs_vnode.c | 25 ++++++++++++++++---------
sys/sys/vnode.h | 26 ++++++++++++++------------
2 files changed, 30 insertions(+), 21 deletions(-)
diffs (107 lines):
diff -r 5042bc140e12 -r 6a14e9f70fc3 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c Thu Aug 04 21:11:52 2022 +0000
+++ b/sys/kern/vfs_vnode.c Fri Aug 05 05:20:39 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.144 2022/07/18 04:30:30 thorpej Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.145 2022/08/05 05:20:39 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.144 2022/07/18 04:30:30 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.145 2022/08/05 05:20:39 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_pax.h"
@@ -1455,8 +1455,7 @@
mutex_obj_free(vp->v_interlock);
rw_destroy(&vip->vi_lock);
uvm_obj_destroy(&vp->v_uobj, true);
- KASSERT(vp->v_klist == &vip->vi_klist ||
- SLIST_EMPTY(&vip->vi_klist.vk_klist));
+ KASSERT(vp->v_klist == &vip->vi_klist);
klist_fini(&vip->vi_klist.vk_klist);
cv_destroy(&vp->v_cv);
cache_vnode_fini(vp);
@@ -1830,6 +1829,19 @@
* while we clean it out.
*/
VSTATE_CHANGE(vp, VS_BLOCKED, VS_RECLAIMING);
+
+ /*
+ * Send NOTE_REVOKE now, before we call VOP_RECLAIM(),
+ * because VOP_RECLAIM() could cause vp->v_klist to
+ * become invalid. Don't check for interest in NOTE_REVOKE
+ * here; it's always posted because it sets EV_EOF.
+ *
+ * Once it's been posted, reset vp->v_klist to point to
+ * our own local storage, in case we were sharing with
+ * someone else.
+ */
+ KNOTE(&vp->v_klist->vk_klist, NOTE_REVOKE);
+ vp->v_klist = &vip->vi_klist;
mutex_exit(vp->v_interlock);
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER);
@@ -1916,11 +1928,6 @@
vp->v_op = dead_vnodeop_p;
VSTATE_CHANGE(vp, VS_RECLAIMING, VS_RECLAIMED);
vp->v_tag = VT_NON;
- /*
- * Don't check for interest in NOTE_REVOKE; it's always posted
- * because it sets EV_EOF.
- */
- KNOTE(&vp->v_klist->vk_klist, NOTE_REVOKE);
mutex_exit(vp->v_interlock);
/*
diff -r 5042bc140e12 -r 6a14e9f70fc3 sys/sys/vnode.h
--- a/sys/sys/vnode.h Thu Aug 04 21:11:52 2022 +0000
+++ b/sys/sys/vnode.h Fri Aug 05 05:20:39 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vnode.h,v 1.302 2022/07/18 04:30:30 thorpej Exp $ */
+/* $NetBSD: vnode.h,v 1.303 2022/08/05 05:20:39 thorpej Exp $ */
/*-
* Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
@@ -427,24 +427,26 @@
/*
* Macro to determine kevent interest on a vnode.
*/
-#define VN_KEVENT_INTEREST(vp, n) \
+#define _VN_KEVENT_INTEREST(vp, n) \
(((vp)->v_klist->vk_interest & (n)) != 0)
+static inline bool
+VN_KEVENT_INTEREST(struct vnode *vp, long hint)
+{
+ mutex_enter(vp->v_interlock);
+ bool rv = _VN_KEVENT_INTEREST(vp, hint);
+ mutex_exit(vp->v_interlock);
+ return rv;
+}
+
static inline void
VN_KNOTE(struct vnode *vp, long hint)
{
- /*
- * Testing for klist interest unlocked is fine here, as registering
- * interest in vnode events is inherently racy with respect to other
- * system activity anyway. Having knotes attached to vnodes is
- * actually incredibly rare, so we want to void having to take locks,
- * etc. in what is the overwhelmingly common case.
- */
- if (__predict_false(VN_KEVENT_INTEREST(vp, hint))) {
- mutex_enter(vp->v_interlock);
+ mutex_enter(vp->v_interlock);
+ if (__predict_false(_VN_KEVENT_INTEREST(vp, hint))) {
knote(&vp->v_klist->vk_klist, hint);
- mutex_exit(vp->v_interlock);
}
+ mutex_exit(vp->v_interlock);
}
void vn_knote_attach(struct vnode *, struct knote *);
Home |
Main Index |
Thread Index |
Old Index