Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F170759272
D29324.id85963.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D29324.id85963.diff
View Options
Index: sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c
===================================================================
--- sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c
+++ sys/contrib/openzfs/module/os/freebsd/zfs/arc_os.c
@@ -51,6 +51,9 @@
#include <sys/vm.h>
#include <sys/vmmeter.h>
+static struct sx arc_vnlru_lock;
+static struct vnode *arc_vnlru_marker;
+
extern struct vfsops zfs_vfsops;
uint_t zfs_arc_free_target = 0;
@@ -157,7 +160,9 @@
arc_reduce_target_size(ptob(nr_scan));
free(arg, M_TEMP);
- vnlru_free(nr_scan, &zfs_vfsops);
+ sx_xlock(&arc_vnlru_lock);
+ vnlru_free_vfsops(nr_scan, &zfs_vfsops, arc_vnlru_marker);
+ sx_xunlock(&arc_vnlru_lock);
}
/*
@@ -234,7 +239,8 @@
{
arc_event_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, arc_lowmem, NULL,
EVENTHANDLER_PRI_FIRST);
-
+ arc_vnlru_marker = vnlru_alloc_marker();
+ sx_init(&arc_vnlru_lock, "arc vnlru lock");
}
void
@@ -242,6 +248,10 @@
{
if (arc_event_lowmem != NULL)
EVENTHANDLER_DEREGISTER(vm_lowmem, arc_event_lowmem);
+ if (arc_vnlru_marker != NULL) {
+ vnlru_free_marker(arc_vnlru_marker);
+ sx_destroy(&arc_vnlru_lock);
+ }
}
void
Index: sys/kern/vfs_subr.c
===================================================================
--- sys/kern/vfs_subr.c
+++ sys/kern/vfs_subr.c
@@ -1216,9 +1216,9 @@
* Attempt to reduce the free list by the requested amount.
*/
static int
-vnlru_free_locked(int count, struct vfsops *mnt_op)
+vnlru_free_impl(int count, struct vfsops *mnt_op, struct vnode *mvp)
{
- struct vnode *vp, *mvp;
+ struct vnode *vp;
struct mount *mp;
int ocount;
@@ -1226,7 +1226,6 @@
if (count > max_vnlru_free)
count = max_vnlru_free;
ocount = count;
- mvp = vnode_list_free_marker;
vp = mvp;
for (;;) {
if (count == 0) {
@@ -1268,13 +1267,72 @@
return (ocount - count);
}
+static int
+vnlru_free_locked(int count)
+{
+
+ mtx_assert(&vnode_list_mtx, MA_OWNED);
+ return (vnlru_free_impl(count, NULL, vnode_list_free_marker));
+}
+
+void
+vnlru_free_vfsops(int count, struct vfsops *mnt_op, struct vnode *mvp)
+{
+
+ MPASS(mnt_op != NULL);
+ MPASS(mvp != NULL);
+ VNPASS(mvp->v_type == VMARKER, mvp);
+ mtx_lock(&vnode_list_mtx);
+ vnlru_free_impl(count, mnt_op, mvp);
+ mtx_unlock(&vnode_list_mtx);
+}
+
+/*
+ * Temporary binary compat, don't use. Call vnlru_free_vfsops instead.
+ */
void
vnlru_free(int count, struct vfsops *mnt_op)
{
+ struct vnode *mvp;
+
+ if (count == 0)
+ return;
+ mtx_lock(&vnode_list_mtx);
+ mvp = vnode_list_free_marker;
+ if (vnlru_free_impl(count, mnt_op, mvp) == 0) {
+ /*
+ * It is possible the marker was moved over eligible vnodes by
+ * callers which filtered by different ops. If so, start from
+ * scratch.
+ */
+ if (vnlru_read_freevnodes() > 0) {
+ TAILQ_REMOVE(&vnode_list, mvp, v_vnodelist);
+ TAILQ_INSERT_HEAD(&vnode_list, mvp, v_vnodelist);
+ }
+ vnlru_free_impl(count, mnt_op, mvp);
+ }
+ mtx_unlock(&vnode_list_mtx);
+}
+
+struct vnode *
+vnlru_alloc_marker(void)
+{
+ struct vnode *mvp;
+ mvp = vn_alloc_marker(NULL);
+ mtx_lock(&vnode_list_mtx);
+ TAILQ_INSERT_BEFORE(vnode_list_free_marker, mvp, v_vnodelist);
+ mtx_unlock(&vnode_list_mtx);
+ return (mvp);
+}
+
+void
+vnlru_free_marker(struct vnode *mvp)
+{
mtx_lock(&vnode_list_mtx);
- vnlru_free_locked(count, mnt_op);
+ TAILQ_REMOVE(&vnode_list, mvp, v_vnodelist);
mtx_unlock(&vnode_list_mtx);
+ vn_free_marker(mvp);
}
static void
@@ -1423,7 +1481,7 @@
* try to reduce it by discarding from the free list.
*/
if (rnumvnodes > desiredvnodes) {
- vnlru_free_locked(rnumvnodes - desiredvnodes, NULL);
+ vnlru_free_locked(rnumvnodes - desiredvnodes);
rnumvnodes = atomic_load_long(&numvnodes);
}
/*
@@ -1615,7 +1673,7 @@
* should be chosen so that we never wait or even reclaim from
* the free list to below its target minimum.
*/
- if (vnlru_free_locked(1, NULL) > 0)
+ if (vnlru_free_locked(1) > 0)
goto alloc;
if (mp == NULL || (mp->mnt_kern_flag & MNTK_SUSPEND) == 0) {
/*
@@ -1625,7 +1683,7 @@
msleep(&vnlruproc_sig, &vnode_list_mtx, PVFS, "vlruwk", hz);
if (atomic_load_long(&numvnodes) + 1 > desiredvnodes &&
vnlru_read_freevnodes() > 1)
- vnlru_free_locked(1, NULL);
+ vnlru_free_locked(1);
}
alloc:
rnumvnodes = atomic_fetchadd_long(&numvnodes, 1) + 1;
Index: sys/sys/vnode.h
===================================================================
--- sys/sys/vnode.h
+++ sys/sys/vnode.h
@@ -826,7 +826,10 @@
void vfs_write_resume(struct mount *mp, int flags);
int vfs_write_suspend(struct mount *mp, int flags);
int vfs_write_suspend_umnt(struct mount *mp);
+struct vnode *vnlru_alloc_marker(void);
+void vnlru_free_marker(struct vnode *);
void vnlru_free(int, struct vfsops *);
+void vnlru_free_vfsops(int, struct vfsops *, struct vnode *);
int vop_stdbmap(struct vop_bmap_args *);
int vop_stdfdatasync_buf(struct vop_fdatasync_args *);
int vop_stdfsync(struct vop_fsync_args *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Sep 7, 11:18 AM (7 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38464852
Default Alt Text
D29324.id85963.diff (4 KB)
Attached To
Mode
D29324: vfs: fix vnlru marker handling for filtered/unfiltered cases
Attached
Detach File
Event Timeline
Log In to Comment