rename Move vnode members "v_freelisthd" and "v_freelist" from "struct vnode" to "struct vnode_impl" and rename to "vi_lrulisthd" and "vi_lrulist". No functional change intended. Welcome to 7.99.XX diff -r 4091fa48cd30 -r f7bff9a8bae7 share/man/man9/vnode.9 --- a/share/man/man9/vnode.9 Fri Dec 09 10:58:19 2016 +0100 +++ b/share/man/man9/vnode.9 Fri Dec 09 10:58:36 2016 +0100 @@ -175,8 +175,6 @@ int v_synclist_slot; /* synclist slot index */ struct mount *v_mount; /* ptr to vfs we are in */ int (**v_op)(void *); /* vnode operations vector */ - TAILQ_ENTRY(vnode) v_freelist; /* vnode freelist */ - struct vnodelst *v_freelisthd; /* which freelist? */ TAILQ_ENTRY(vnode) v_mntvnodes; /* vnodes for mount point */ struct buflists v_cleanblkhd; /* clean blocklist head */ struct buflists v_dirtyblkhd; /* dirty blocklist head */ @@ -300,11 +298,8 @@ .Em v_usecount and .Em v_holdcnt -reach zero, the vnode is recycled to the freelist and may be reused -for another file. -The transition to and from the freelist is handled by -a kernel thread -and +reach zero, the vnode is cached. +The transition from the cache is handled by a kernel thread and .Fn vrecycle . Access to .Em v_usecount , @@ -354,14 +349,9 @@ .Xr vnodeops 9 for a description of vnode operations. .Pp -When not in use, vnodes are kept on the freelist through -.Em v_freelist . -The vnodes still reference valid files but may be reused to refer to a -new file at any time. -When a valid vnode which is on the freelist is used again, the user -must call +When a valid vnode which is cached is used again, the user must call .Fn vget -to increment the reference count and retrieve it from the freelist. +to increment the reference count. When a user wants a new vnode for another file, .Fn vcache_get or @@ -512,7 +502,6 @@ .Em v_holdcnt , .Em v_dirtyblkhd , .Em v_cleanblkhd , -.Em v_freelist , and .Em v_synclist are modified in interrupt context and must be protected by @@ -547,14 +536,14 @@ .Em v_usecount and .Em v_holdcnt -are zero, the vnode is placed on the freelist. +are zero, the vnode is cached. .It Fn vrele_async "vp" Will asychronously release the vnode in different context than the caller, sometime after the call. .It Fn vget "vp" "lockflags" "wait" Reclaim vnode .Fa vp -from the freelist and increment its reference count. +from the cache and increment its reference count. .Pp The vnode .Fa vp @@ -628,17 +617,15 @@ Mark the vnode .Fa vp as active by incrementing -.Em vp-\*[Gt]v_holdcnt -and moving the vnode from the freelist to the holdlist. -Once on the holdlist, the vnode will not be recycled until it is +.Em vp-\*[Gt]v_holdcnt . +Once held, the vnode will not be recycled until it is released with .Fn holdrele . .It Fn holdrele "vp" Mark the vnode .Fa vp as inactive by decrementing -.Em vp-\*[Gt]v_holdcnt -and moving the vnode from the holdlist to the freelist. +.Em vp-\*[Gt]v_holdcnt . .It Fn vcache_get "mp" "key" "key_len" "vpp" Allocate a new vnode. The new vnode is returned referenced in the address specified by diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/fs/msdosfs/msdosfs_vfsops.c --- a/sys/fs/msdosfs/msdosfs_vfsops.c Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/fs/msdosfs/msdosfs_vfsops.c Fri Dec 09 10:58:36 2016 +0100 @@ -904,9 +904,6 @@ vp->v_writecount, vp->v_holdcnt); printf("mount %p, op %p\n", vp->v_mount, vp->v_op); - printf("freef %p, freeb %p, mount %p\n", - vp->v_freelist.tqe_next, vp->v_freelist.tqe_prev, - vp->v_mount); printf("cleanblkhd %p, dirtyblkhd %p, numoutput %d, type %d\n", vp->v_cleanblkhd.lh_first, vp->v_dirtyblkhd.lh_first, diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/gdbscripts/vchain --- a/sys/gdbscripts/vchain Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/gdbscripts/vchain Fri Dec 09 10:58:36 2016 +0100 @@ -7,9 +7,10 @@ set $num = 0 set $vp=(struct vnode *)$arg0 + set $vi=(struct vnode_impl *)$arg0 while ($vp) - printf "vp: 0x%lx freelist_next: 0x%lx usecount: %d flags: i:0x%x v:0x%x u:0x%x\n",\ - $vp, $vp->v_freelist.tqe_next, $vp->v_uobj.uo_refs, \ + printf "vp: 0x%lx lrulist_next: 0x%lx usecount: %d flags: i:0x%x v:0x%x u:0x%x\n",\ + $vp, $vi->vi_lrulist.tqe_next, $vp->v_uobj.uo_refs, \ $vp->v_iflag, $vp->v_vflag, $vp->v_uflag set $num++ set $vp = $vp->v_mntvnodes.tqe_next diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/gdbscripts/vdump --- a/sys/gdbscripts/vdump Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/gdbscripts/vdump Fri Dec 09 10:58:36 2016 +0100 @@ -6,12 +6,14 @@ define dumpvnodes set $vp = (struct vnode *)$arg0 + set $vi = (struct vnode_impl *)$arg0 while ($vp) - printf "vnode=0x%x freef=0x%x mountf=0x%x usecount=%d\n", $vp, $vp->v_freelist.tqe_next, $vp->v_mntvnodes.tqe_next, $vp->v_uobj.uo_refs - set $vp = (struct vnode *)$vp->v_freelist.tqe_next + printf "vnode=0x%x lruf=0x%x mountf=0x%x usecount=%d\n", $vp, $vi->vi_lrulist.tqe_next, $vp->v_mntvnodes.tqe_next, $vp->v_uobj.uo_refs + set $vi = (struct vnode_impl *)$vi->vi_lrulist.tqe_next + set $vp = (struct vnode *)$vi end end document dumpvnodes dump the vnode list -end \ No newline at end of file +end diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/kern/vfs_subr.c --- a/sys/kern/vfs_subr.c Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/kern/vfs_subr.c Fri Dec 09 10:58:36 2016 +0100 @@ -1114,8 +1114,7 @@ vp->v_usecount, vp->v_writecount, vp->v_holdcnt); (*pr)("%ssize %" PRIx64 " writesize %" PRIx64 " numoutput %d\n", prefix, vp->v_size, vp->v_writesize, vp->v_numoutput); - (*pr)("%sfreelisthd %p data %p lock %p\n", prefix, - vp->v_freelisthd, vp->v_data, &vp->v_lock); + (*pr)("%sdata %p lock %p\n", prefix, vp->v_data, &vp->v_lock); (*pr)("%sstate %s key(%p %zd)", prefix, vstate_name(node->vi_state), node->vi_key.vk_mount, node->vi_key.vk_key_len); @@ -1124,6 +1123,7 @@ while (n-- > 0) (*pr)(" %02x", *cp++); (*pr)("\n"); + (*pr)("%slrulisthd %p\n", prefix, node->vi_lrulisthd); #undef ARRAY_PRINT #undef ARRAY_SIZE diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/kern/vfs_vnode.c --- a/sys/kern/vfs_vnode.c Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/kern/vfs_vnode.c Fri Dec 09 10:58:36 2016 +0100 @@ -428,6 +428,7 @@ cleanvnode(void) { vnode_t *vp; + vnode_impl_t *vi; vnodelst_t *listhd; struct mount *mp; @@ -435,7 +436,8 @@ listhd = &vnode_free_list; try_nextlist: - TAILQ_FOREACH(vp, listhd, v_freelist) { + TAILQ_FOREACH(vi, listhd, vi_lrulist) { + vp = VIMPL_TO_VNODE(vi); /* * It's safe to test v_usecount and v_iflag * without holding the interlock here, since @@ -443,7 +445,7 @@ * lists. */ KASSERT(vp->v_usecount == 0); - KASSERT(vp->v_freelisthd == listhd); + KASSERT(vi->vi_lrulisthd == listhd); if (!mutex_tryenter(vp->v_interlock)) continue; @@ -455,7 +457,7 @@ break; } - if (vp == NULL) { + if (vi == NULL) { if (listhd == &vnode_free_list) { listhd = &vnode_hold_list; goto try_nextlist; @@ -504,6 +506,7 @@ void vremfree(vnode_t *vp) { + vnode_impl_t *vi = VNODE_TO_VIMPL(vp); KASSERT(mutex_owned(vp->v_interlock)); KASSERT(vp->v_usecount == 0); @@ -514,12 +517,12 @@ */ mutex_enter(&vnode_free_list_lock); if (vp->v_holdcnt > 0) { - KASSERT(vp->v_freelisthd == &vnode_hold_list); + KASSERT(vi->vi_lrulisthd == &vnode_hold_list); } else { - KASSERT(vp->v_freelisthd == &vnode_free_list); + KASSERT(vi->vi_lrulisthd == &vnode_free_list); } - TAILQ_REMOVE(vp->v_freelisthd, vp, v_freelist); - vp->v_freelisthd = NULL; + TAILQ_REMOVE(vi->vi_lrulisthd, vi, vi_lrulist); + vi->vi_lrulisthd = NULL; mutex_exit(&vnode_free_list_lock); } @@ -620,11 +623,12 @@ static void vrelel(vnode_t *vp, int flags) { + vnode_impl_t *vi = VNODE_TO_VIMPL(vp); bool recycle, defer; int error; KASSERT(mutex_owned(vp->v_interlock)); - KASSERT(vp->v_freelisthd == NULL); + KASSERT(vi->vi_lrulisthd == NULL); if (__predict_false(vp->v_op == dead_vnodeop_p && VSTATE_GET(vp) != VS_RECLAIMED)) { @@ -694,7 +698,7 @@ * clean it here. We donate it our last reference. */ mutex_enter(&vrele_lock); - TAILQ_INSERT_TAIL(&vrele_list, vp, v_freelist); + TAILQ_INSERT_TAIL(&vrele_list, vi, vi_lrulist); if (++vrele_pending > (desiredvnodes >> 8)) cv_signal(&vrele_cv); mutex_exit(&vrele_lock); @@ -785,11 +789,11 @@ */ mutex_enter(&vnode_free_list_lock); if (vp->v_holdcnt > 0) { - vp->v_freelisthd = &vnode_hold_list; + vi->vi_lrulisthd = &vnode_hold_list; } else { - vp->v_freelisthd = &vnode_free_list; + vi->vi_lrulisthd = &vnode_free_list; } - TAILQ_INSERT_TAIL(vp->v_freelisthd, vp, v_freelist); + TAILQ_INSERT_TAIL(vi->vi_lrulisthd, vi, vi_lrulist); mutex_exit(&vnode_free_list_lock); mutex_exit(vp->v_interlock); } @@ -825,6 +829,7 @@ { vnodelst_t skip_list; vnode_t *vp; + vnode_impl_t *vi; struct mount *mp; TAILQ_INIT(&skip_list); @@ -835,13 +840,14 @@ vrele_gen++; cv_broadcast(&vrele_cv); cv_timedwait(&vrele_cv, &vrele_lock, hz); - TAILQ_CONCAT(&vrele_list, &skip_list, v_freelist); + TAILQ_CONCAT(&vrele_list, &skip_list, vi_lrulist); } - vp = TAILQ_FIRST(&vrele_list); + vi = TAILQ_FIRST(&vrele_list); + vp = VIMPL_TO_VNODE(vi); mp = vp->v_mount; - TAILQ_REMOVE(&vrele_list, vp, v_freelist); + TAILQ_REMOVE(&vrele_list, vi, vi_lrulist); if (fstrans_start_nowait(mp, FSTRANS_LAZY) != 0) { - TAILQ_INSERT_TAIL(&skip_list, vp, v_freelist); + TAILQ_INSERT_TAIL(&skip_list, vi, vi_lrulist); continue; } vrele_pending--; @@ -878,15 +884,16 @@ void vholdl(vnode_t *vp) { + vnode_impl_t *vi = VNODE_TO_VIMPL(vp); KASSERT(mutex_owned(vp->v_interlock)); if (vp->v_holdcnt++ == 0 && vp->v_usecount == 0) { mutex_enter(&vnode_free_list_lock); - KASSERT(vp->v_freelisthd == &vnode_free_list); - TAILQ_REMOVE(vp->v_freelisthd, vp, v_freelist); - vp->v_freelisthd = &vnode_hold_list; - TAILQ_INSERT_TAIL(vp->v_freelisthd, vp, v_freelist); + KASSERT(vi->vi_lrulisthd == &vnode_free_list); + TAILQ_REMOVE(vi->vi_lrulisthd, vi, vi_lrulist); + vi->vi_lrulisthd = &vnode_hold_list; + TAILQ_INSERT_TAIL(vi->vi_lrulisthd, vi, vi_lrulist); mutex_exit(&vnode_free_list_lock); } } @@ -898,6 +905,7 @@ void holdrelel(vnode_t *vp) { + vnode_impl_t *vi = VNODE_TO_VIMPL(vp); KASSERT(mutex_owned(vp->v_interlock)); @@ -908,10 +916,10 @@ vp->v_holdcnt--; if (vp->v_holdcnt == 0 && vp->v_usecount == 0) { mutex_enter(&vnode_free_list_lock); - KASSERT(vp->v_freelisthd == &vnode_hold_list); - TAILQ_REMOVE(vp->v_freelisthd, vp, v_freelist); - vp->v_freelisthd = &vnode_free_list; - TAILQ_INSERT_TAIL(vp->v_freelisthd, vp, v_freelist); + KASSERT(vi->vi_lrulisthd == &vnode_hold_list); + TAILQ_REMOVE(vi->vi_lrulisthd, vi, vi_lrulist); + vi->vi_lrulisthd = &vnode_free_list; + TAILQ_INSERT_TAIL(vi->vi_lrulisthd, vi, vi_lrulist); mutex_exit(&vnode_free_list_lock); } } diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/sys/vnode.h --- a/sys/sys/vnode.h Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/sys/vnode.h Fri Dec 09 10:58:36 2016 +0100 @@ -119,7 +119,6 @@ struct buf; LIST_HEAD(buflists, buf); -TAILQ_HEAD(vnodelst, vnode); /* * Reading or writing any of these items requires holding the appropriate @@ -152,8 +151,6 @@ int v_synclist_slot; /* s: synclist slot index */ struct mount *v_mount; /* v: ptr to vfs we are in */ int (**v_op)(void *); /* :: vnode operations vector */ - TAILQ_ENTRY(vnode) v_freelist; /* f: vnode freelist */ - struct vnodelst *v_freelisthd; /* f: which freelist? */ TAILQ_ENTRY(vnode) v_mntvnodes; /* m: vnodes for mount point */ struct buflists v_cleanblkhd; /* x: clean blocklist head */ struct buflists v_dirtyblkhd; /* x: dirty blocklist head */ @@ -181,7 +178,6 @@ #define v_fifoinfo v_un.vu_fifoinfo #define v_ractx v_un.vu_ractx -typedef struct vnodelst vnodelst_t; typedef struct vnode vnode_t; #endif diff -r 4091fa48cd30 -r f7bff9a8bae7 sys/sys/vnode_impl.h --- a/sys/sys/vnode_impl.h Fri Dec 09 10:58:19 2016 +0100 +++ b/sys/sys/vnode_impl.h Fri Dec 09 10:58:36 2016 +0100 @@ -42,6 +42,8 @@ VS_RECLAIMING, /* Intermediate, detaching the fs node. */ VS_RECLAIMED /* Stable, no fs node attached. */ }; +TAILQ_HEAD(vnodelst, vnode_impl); +typedef struct vnodelst vnodelst_t; struct vcache_key { struct mount *vk_mount; const void *vk_key; @@ -50,6 +52,8 @@ struct vnode_impl { struct vnode vi_vnode; enum vnode_state vi_state; + struct vnodelst *vi_lrulisthd; + TAILQ_ENTRY(vnode_impl) vi_lrulist; SLIST_ENTRY(vnode_impl) vi_hash; struct vcache_key vi_key; };