diff options
author | Mateusz Guzik <mjg@FreeBSD.org> | 2017-09-30 18:23:45 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2017-09-30 18:23:45 +0000 |
commit | e3e10c39f10f034d4eb6ba74f20cf3d7e37308ca (patch) | |
tree | 517d65791e6b02940a1e3d33400e4ca359cc0fe2 | |
parent | f3b5058c8ef9351b64b71188748d503ee714f70f (diff) | |
download | src-e3e10c39f10f034d4eb6ba74f20cf3d7e37308ca.tar.gz src-e3e10c39f10f034d4eb6ba74f20cf3d7e37308ca.zip |
tmpfs: skip zero-sized page count updates
Such updates consisted of vast majority of modificiations, especially
in tmpfs_reg_resize.
For the case where page count did no change and the size grew we only
need to update tn_size. Use this fact to avoid vm object lock/relock.
MFC after: 1 week
Notes
Notes:
svn path=/head/; revision=324127
-rw-r--r-- | sys/fs/tmpfs/tmpfs_subr.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index b04d28ba4055..10acd4b17167 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -350,7 +350,8 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node, case VREG: uobj = node->tn_reg.tn_aobj; if (uobj != NULL) { - atomic_subtract_long(&tmp->tm_pages_used, uobj->size); + if (uobj->size != 0) + atomic_subtract_long(&tmp->tm_pages_used, uobj->size); KASSERT((uobj->flags & OBJ_TMPFS) == 0, ("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj)); vm_object_deallocate(uobj); @@ -1375,6 +1376,12 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr) oldpages = OFF_TO_IDX(oldsize + PAGE_MASK); MPASS(oldpages == uobj->size); newpages = OFF_TO_IDX(newsize + PAGE_MASK); + + if (__predict_true(newpages == oldpages && newsize >= oldsize)) { + node->tn_size = newsize; + return (0); + } + if (newpages > oldpages && tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0) return (ENOSPC); |