aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c6
-rw-r--r--sys/kern/kern_thread.c2
-rw-r--r--sys/kern/subr_trap.c4
-rw-r--r--sys/kern/vfs_subr.c54
-rw-r--r--sys/sys/proc.h2
-rw-r--r--sys/sys/vnode.h2
8 files changed, 35 insertions, 43 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
index c60d8c957b59..c3621a24d137 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
@@ -815,7 +815,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr)
return (SET_ERROR(EDQUOT));
}
- getnewvnode_reserve(1);
+ getnewvnode_reserve();
tx = dmu_tx_create(zfsvfs->z_os);
dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index b1921a8d4f0a..596bbb5ad2f4 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -1800,7 +1800,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode,
goto out;
}
- getnewvnode_reserve(1);
+ getnewvnode_reserve();
tx = dmu_tx_create(os);
@@ -2092,7 +2092,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr)
/*
* Add a new entry to the directory.
*/
- getnewvnode_reserve(1);
+ getnewvnode_reserve();
tx = dmu_tx_create(zfsvfs->z_os);
dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname);
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
@@ -4003,7 +4003,7 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
return (SET_ERROR(EDQUOT));
}
- getnewvnode_reserve(1);
+ getnewvnode_reserve();
tx = dmu_tx_create(zfsvfs->z_os);
fuid_dirtied = zfsvfs->z_fuid_dirty;
dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, MAX(1, len));
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
index 62ea41ca07b5..14b9298c2d34 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
@@ -644,8 +644,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
- KASSERT(curthread->td_vp_reserv > 0,
- ("zfs_znode_alloc: getnewvnode without any vnodes reserved"));
+ KASSERT(curthread->td_vp_reserved != NULL,
+ ("zfs_znode_alloc: getnewvnode without preallocated vnode"));
error = getnewvnode("zfs", zfsvfs->z_parent->z_vfs, &zfs_vnodeops, &vp);
if (error != 0) {
kmem_cache_free(znode_cache, zp);
@@ -1157,7 +1157,7 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp)
int err;
td = curthread;
- getnewvnode_reserve(1);
+ getnewvnode_reserve();
again:
*zpp = NULL;
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num);
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index dddf4997667a..9095a32c6a58 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -82,7 +82,7 @@ _Static_assert(offsetof(struct thread, td_flags) == 0xfc,
"struct thread KBI td_flags");
_Static_assert(offsetof(struct thread, td_pflags) == 0x104,
"struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x478,
+_Static_assert(offsetof(struct thread, td_frame) == 0x480,
"struct thread KBI td_frame");
_Static_assert(offsetof(struct thread, td_emuldata) == 0x690,
"struct thread KBI td_emuldata");
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 2abbc67de40c..3285272b1855 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -187,8 +187,8 @@ userret(struct thread *td, struct trapframe *frame)
}
KASSERT(td->td_pinned == 0 || (td->td_pflags & TDP_CALLCHAIN) != 0,
("userret: Returning with with pinned thread"));
- KASSERT(td->td_vp_reserv == 0,
- ("userret: Returning while holding vnode reservation"));
+ KASSERT(td->td_vp_reserved == NULL,
+ ("userret: Returning with preallocated vnode"));
KASSERT((td->td_flags & (TDF_SBDRY | TDF_SEINTR | TDF_SERESTART)) == 0,
("userret: Returning with stop signals deferred"));
KASSERT(td->td_su == NULL,
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index d65839d66722..86bfae82154d 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1527,40 +1527,29 @@ getnewvnode_wait(int suspended)
* watermark handling works.
*/
void
-getnewvnode_reserve(u_int count)
+getnewvnode_reserve(void)
{
u_long rnumvnodes, rfreevnodes;
struct thread *td;
- /* Pre-adjust like the pre-adjust in getnewvnode(), with any count. */
- /* XXX no longer so quick, but this part is not racy. */
+ td = curthread;
+ MPASS(td->td_vp_reserved == NULL);
+
mtx_lock(&vnode_free_list_mtx);
rnumvnodes = atomic_load_long(&numvnodes);
rfreevnodes = atomic_load_long(&freevnodes);
- if (rnumvnodes + count > desiredvnodes && rfreevnodes > wantfreevnodes)
- vnlru_free_locked(ulmin(rnumvnodes + count - desiredvnodes,
+ if (rnumvnodes + 1 > desiredvnodes && rfreevnodes > wantfreevnodes)
+ vnlru_free_locked(ulmin(rnumvnodes + 1 - desiredvnodes,
rfreevnodes - wantfreevnodes), NULL);
- mtx_unlock(&vnode_free_list_mtx);
-
- td = curthread;
- /* First try to be quick and racy. */
- if (atomic_fetchadd_long(&numvnodes, count) + count <= desiredvnodes) {
- td->td_vp_reserv += count;
- vcheckspace(); /* XXX no longer so quick, but more racy */
- return;
- } else
- atomic_subtract_long(&numvnodes, count);
-
- mtx_lock(&vnode_free_list_mtx);
- while (count > 0) {
- if (getnewvnode_wait(0) == 0) {
- count--;
- td->td_vp_reserv++;
- atomic_add_long(&numvnodes, 1);
- }
+ if (rnumvnodes + 1 > desiredvnodes) {
+ while (getnewvnode_wait(0) != 0)
+ continue;
}
vcheckspace();
+ atomic_add_long(&numvnodes, 1);
mtx_unlock(&vnode_free_list_mtx);
+
+ td->td_vp_reserved = uma_zalloc(vnode_zone, M_WAITOK);
}
/*
@@ -1577,8 +1566,11 @@ getnewvnode_drop_reserve(void)
struct thread *td;
td = curthread;
- atomic_subtract_long(&numvnodes, td->td_vp_reserv);
- td->td_vp_reserv = 0;
+ if (td->td_vp_reserved != NULL) {
+ atomic_subtract_long(&numvnodes, 1);
+ uma_zfree(vnode_zone, td->td_vp_reserved);
+ td->td_vp_reserved = NULL;
+ }
}
/*
@@ -1599,11 +1591,11 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
KASSERT(vops->registered,
("%s: not registered vector op %p\n", __func__, vops));
- vp = NULL;
td = curthread;
- if (td->td_vp_reserv > 0) {
- td->td_vp_reserv -= 1;
- goto alloc;
+ if (td->td_vp_reserved != NULL) {
+ vp = td->td_vp_reserved;
+ td->td_vp_reserved = NULL;
+ goto init;
}
mtx_lock(&vnode_free_list_mtx);
if (numvnodes < desiredvnodes)
@@ -1639,9 +1631,9 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
vcheckspace();
atomic_add_long(&numvnodes, 1);
mtx_unlock(&vnode_free_list_mtx);
-alloc:
- counter_u64_add(vnodes_created, 1);
vp = (struct vnode *) uma_zalloc(vnode_zone, M_WAITOK);
+init:
+ counter_u64_add(vnodes_created, 1);
/*
* Locks are given the generic name "vnode" when created.
* Follow the historic practice of using the filesystem
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 64605b174733..2a85b035a7b4 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -297,7 +297,7 @@ struct thread {
struct osd td_osd; /* (k) Object specific data. */
struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */
pid_t td_dbg_forked; /* (c) Child pid for debugger. */
- u_int td_vp_reserv; /* (k) Count of reserved vnodes. */
+ struct vnode *td_vp_reserved;/* (k) Prealloated vnode. */
u_int td_no_sleeping; /* (k) Sleeping disabled count. */
void *td_su; /* (k) FFS SU private */
sbintime_t td_sleeptimo; /* (t) Sleep timeout. */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 98a12bbea962..2065b467a5e8 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -624,7 +624,7 @@ void freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb);
int freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost);
int getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
struct vnode **vpp);
-void getnewvnode_reserve(u_int count);
+void getnewvnode_reserve(void);
void getnewvnode_drop_reserve(void);
int insmntque1(struct vnode *vp, struct mount *mp,
void (*dtr)(struct vnode *, void *), void *dtr_arg);