aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-08-10 10:36:43 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-08-10 10:36:43 +0000
commit7b19bddac8f6ae5a356ffbca80f087d3654b8363 (patch)
tree7b1204004bbdbdd2466532eb9e45efe1c597e162 /sys/fs
parentf8935a96d1bc34839cf10ea1ddc45afbdab513d4 (diff)
downloadsrc-7b19bddac8f6ae5a356ffbca80f087d3654b8363.tar.gz
src-7b19bddac8f6ae5a356ffbca80f087d3654b8363.zip
devfs: save on spurious relocking for devfs_populate
Tested by: pho
Notes
Notes: svn path=/head/; revision=364069
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/devfs/devfs.h1
-rw-r--r--sys/fs/devfs/devfs_devs.c11
-rw-r--r--sys/fs/devfs/devfs_vnops.c6
3 files changed, 16 insertions, 2 deletions
diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h
index 5f64a2672799..121d6eb6f0b5 100644
--- a/sys/fs/devfs/devfs.h
+++ b/sys/fs/devfs/devfs.h
@@ -192,6 +192,7 @@ char *devfs_fqpn(char *, struct devfs_mount *, struct devfs_dirent *,
struct componentname *);
void devfs_delete(struct devfs_mount *, struct devfs_dirent *, int);
void devfs_dirent_free(struct devfs_dirent *);
+bool devfs_populate_needed(struct devfs_mount *dm);
void devfs_populate(struct devfs_mount *);
void devfs_cleanup(struct devfs_mount *);
void devfs_unmount_final(struct devfs_mount *);
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c
index 417e13e2757a..5df21a3712d0 100644
--- a/sys/fs/devfs/devfs_devs.c
+++ b/sys/fs/devfs/devfs_devs.c
@@ -659,6 +659,13 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup)
return (0);
}
+bool
+devfs_populate_needed(struct devfs_mount *dm)
+{
+
+ return (dm->dm_generation != devfs_generation);
+}
+
/*
* The caller needs to hold the dm for the duration of the call.
*/
@@ -668,9 +675,9 @@ devfs_populate(struct devfs_mount *dm)
unsigned gen;
sx_assert(&dm->dm_lock, SX_XLOCKED);
- gen = devfs_generation;
- if (dm->dm_generation == gen)
+ if (!devfs_populate_needed(dm))
return;
+ gen = devfs_generation;
while (devfs_populate_loop(dm, 0))
continue;
dm->dm_generation = gen;
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 5bd12708b0df..f9e29e0b1c74 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -235,6 +235,11 @@ devfs_populate_vp(struct vnode *vp)
ASSERT_VOP_LOCKED(vp, "devfs_populate_vp");
dmp = VFSTODEVFS(vp->v_mount);
+ if (!devfs_populate_needed(dmp)) {
+ sx_xlock(&dmp->dm_lock);
+ goto out_nopopulate;
+ }
+
locked = VOP_ISLOCKED(vp);
sx_xlock(&dmp->dm_lock);
@@ -252,6 +257,7 @@ devfs_populate_vp(struct vnode *vp)
devfs_unmount_final(dmp);
return (ERESTART);
}
+out_nopopulate:
if (VN_IS_DOOMED(vp)) {
sx_xunlock(&dmp->dm_lock);
return (ERESTART);