Module Name:    src
Committed By:   hannken
Date:           Thu May 26 11:07:33 UTC 2016

Modified Files:
        src/sys/kern: vfs_subr.c vfs_vnode.c
        src/sys/sys: vnode.h

Log Message:
Merge the vnode and its corresponding vcache_node into one
vcache_node structure.

Print the vcache_node part in vprint() and vfs_vnode_print().

Presented on tech-kern@


To generate a diff of this commit:
cvs rdiff -u -r1.448 -r1.449 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.49 -r1.50 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.260 -r1.261 src/sys/sys/vnode.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.448 src/sys/kern/vfs_subr.c:1.449
--- src/sys/kern/vfs_subr.c:1.448	Mon Aug 24 22:50:32 2015
+++ src/sys/kern/vfs_subr.c	Thu May 26 11:07:33 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.448 2015/08/24 22:50:32 pooka Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.449 2016/05/26 11:07:33 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.448 2015/08/24 22:50:32 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.449 2016/05/26 11:07:33 hannken Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -76,6 +76,8 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v
 #include "opt_compat_43.h"
 #endif
 
+#define _VFS_VNODE_PRIVATE	/* for vcache_print(). */
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
@@ -1085,6 +1087,7 @@ vprint(const char *label, struct vnode *
 	    ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type,
 	    vp->v_usecount, vp->v_writecount, vp->v_holdcnt,
 	    vp->v_freelisthd, vp->v_mount, vp->v_data, &vp->v_lock);
+	vcache_print(vp, "\t", printf);
 	if (vp->v_data != NULL) {
 		printf("\t");
 		VOP_PRINT(vp);
@@ -1481,6 +1484,8 @@ vfs_vnode_print(struct vnode *vp, int fu
 
 	(*pr)("v_lock %p\n", &vp->v_lock);
 
+	vcache_print(vp, "", pr);
+
 	if (full) {
 		struct buf *bp;
 

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.49 src/sys/kern/vfs_vnode.c:1.50
--- src/sys/kern/vfs_vnode.c:1.49	Thu May 19 14:50:18 2016
+++ src/sys/kern/vfs_vnode.c	Thu May 26 11:07:33 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.49 2016/05/19 14:50:18 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.50 2016/05/26 11:07:33 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -116,7 +116,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.49 2016/05/19 14:50:18 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.50 2016/05/26 11:07:33 hannken Exp $");
 
 #define _VFS_VNODE_PRIVATE
 
@@ -154,14 +154,16 @@ struct vcache_key {
 	size_t vk_key_len;
 };
 struct vcache_node {
+	struct vnode vn_data;
 	SLIST_ENTRY(vcache_node) vn_hash;
 	struct vnode *vn_vnode;
 	struct vcache_key vn_key;
 };
 
-u_int			numvnodes		__cacheline_aligned;
+#define VN_TO_VP(node)	((vnode_t *)(node))
+#define VP_TO_VN(vp)	((struct vcache_node *)(vp))
 
-static pool_cache_t	vnode_cache		__read_mostly;
+u_int			numvnodes		__cacheline_aligned;
 
 /*
  * There are two free lists: one is for vnodes which have no buffer/page
@@ -189,14 +191,14 @@ static struct {
 }			vcache			__cacheline_aligned;
 
 static int		cleanvnode(void);
+static struct vcache_node *vcache_alloc(void);
+static void		vcache_free(struct vcache_node *);
 static void		vcache_init(void);
 static void		vcache_reinit(void);
 static void		vclean(vnode_t *);
 static void		vrelel(vnode_t *, int);
 static void		vdrain_thread(void *);
 static void		vrele_thread(void *);
-static vnode_t *	vnalloc(struct mount *);
-static void		vnfree(vnode_t *);
 static void		vnpanic(vnode_t *, const char *, ...)
     __printflike(2, 3);
 static void		vwait(vnode_t *, int);
@@ -211,10 +213,6 @@ vfs_vnode_sysinit(void)
 {
 	int error __diagused;
 
-	vnode_cache = pool_cache_init(sizeof(vnode_t), 0, 0, 0, "vnodepl",
-	    NULL, IPL_NONE, NULL, NULL, NULL);
-	KASSERT(vnode_cache != NULL);
-
 	dead_rootmount = vfs_mountalloc(&dead_vfsops, NULL);
 	KASSERT(dead_rootmount != NULL);
 	dead_rootmount->mnt_iflag = IMNT_MPSAFE;
@@ -243,8 +241,18 @@ vfs_vnode_sysinit(void)
 vnode_t *
 vnalloc_marker(struct mount *mp)
 {
+	struct vcache_node *node;
+	vnode_t *vp;
+
+	node = pool_cache_get(vcache.pool, PR_WAITOK);
+	memset(node, 0, sizeof(*node));
+	vp = VN_TO_VP(node);
+	uvm_obj_init(&vp->v_uobj, &uvm_vnodeops, true, 0);
+	vp->v_mount = mp;
+	vp->v_type = VBAD;
+	vp->v_iflag = VI_MARKER;
 
-	return vnalloc(mp);
+	return vp;
 }
 
 /*
@@ -253,9 +261,12 @@ vnalloc_marker(struct mount *mp)
 void
 vnfree_marker(vnode_t *vp)
 {
+	struct vcache_node *node;
 
+	node = VP_TO_VN(vp);
 	KASSERT(ISSET(vp->v_iflag, VI_MARKER));
-	vnfree(vp);
+	uvm_obj_destroy(&vp->v_uobj, true);
+	pool_cache_put(vcache.pool, node);
 }
 
 /*
@@ -269,69 +280,6 @@ vnis_marker(vnode_t *vp)
 }
 
 /*
- * Allocate a new, uninitialized vnode.  If 'mp' is non-NULL, this is a
- * marker vnode.
- */
-static vnode_t *
-vnalloc(struct mount *mp)
-{
-	vnode_t *vp;
-
-	vp = pool_cache_get(vnode_cache, PR_WAITOK);
-	KASSERT(vp != NULL);
-
-	memset(vp, 0, sizeof(*vp));
-	uvm_obj_init(&vp->v_uobj, &uvm_vnodeops, true, 0);
-	cv_init(&vp->v_cv, "vnode");
-	/*
-	 * Done by memset() above.
-	 *	LIST_INIT(&vp->v_nclist);
-	 *	LIST_INIT(&vp->v_dnclist);
-	 */
-
-	if (mp != NULL) {
-		vp->v_mount = mp;
-		vp->v_type = VBAD;
-		vp->v_iflag = VI_MARKER;
-		return vp;
-	}
-
-	mutex_enter(&vnode_free_list_lock);
-	numvnodes++;
-	if (numvnodes > desiredvnodes + desiredvnodes / 10)
-		cv_signal(&vdrain_cv);
-	mutex_exit(&vnode_free_list_lock);
-
-	rw_init(&vp->v_lock);
-	vp->v_usecount = 1;
-	vp->v_type = VNON;
-	vp->v_size = vp->v_writesize = VSIZENOTSET;
-
-	return vp;
-}
-
-/*
- * Free an unused, unreferenced vnode.
- */
-static void
-vnfree(vnode_t *vp)
-{
-
-	KASSERT(vp->v_usecount == 0);
-
-	if ((vp->v_iflag & VI_MARKER) == 0) {
-		rw_destroy(&vp->v_lock);
-		mutex_enter(&vnode_free_list_lock);
-		numvnodes--;
-		mutex_exit(&vnode_free_list_lock);
-	}
-
-	uvm_obj_destroy(&vp->v_uobj, true);
-	cv_destroy(&vp->v_cv);
-	pool_cache_put(vnode_cache, vp);
-}
-
-/*
  * cleanvnode: grab a vnode from freelist, clean and free it.
  *
  * => Releases vnode_free_list_lock.
@@ -740,7 +688,7 @@ vrelel(vnode_t *vp, int flags)
 		if (vp->v_type == VBLK || vp->v_type == VCHR) {
 			spec_node_destroy(vp);
 		}
-		vnfree(vp);
+		vcache_free(VP_TO_VN(vp));
 	} else {
 		/*
 		 * Otherwise, put it back onto the freelist.  It
@@ -1156,6 +1104,63 @@ vcache_hash_lookup(const struct vcache_k
 }
 
 /*
+ * Allocate a new, uninitialized vcache node.
+ */
+static struct vcache_node *
+vcache_alloc(void)
+{
+	struct vcache_node *node;
+	vnode_t *vp;
+
+	node = pool_cache_get(vcache.pool, PR_WAITOK);
+	memset(node, 0, sizeof(*node));
+
+	/* SLIST_INIT(&node->vn_hash); */
+
+	vp = VN_TO_VP(node);
+	uvm_obj_init(&vp->v_uobj, &uvm_vnodeops, true, 0);
+	cv_init(&vp->v_cv, "vnode");
+	/* LIST_INIT(&vp->v_nclist); */
+	/* LIST_INIT(&vp->v_dnclist); */
+
+	mutex_enter(&vnode_free_list_lock);
+	numvnodes++;
+	if (numvnodes > desiredvnodes + desiredvnodes / 10)
+		cv_signal(&vdrain_cv);
+	mutex_exit(&vnode_free_list_lock);
+
+	rw_init(&vp->v_lock);
+	vp->v_usecount = 1;
+	vp->v_type = VNON;
+	vp->v_size = vp->v_writesize = VSIZENOTSET;
+
+	return node;
+}
+
+/*
+ * Free an unused, unreferenced vcache node.
+ */
+static void
+vcache_free(struct vcache_node *node)
+{
+	vnode_t *vp;
+
+	vp = VN_TO_VP(node);
+
+	KASSERT(vp->v_usecount == 0);
+	KASSERT((vp->v_iflag & VI_MARKER) == 0);
+
+	rw_destroy(&vp->v_lock);
+	mutex_enter(&vnode_free_list_lock);
+	numvnodes--;
+	mutex_exit(&vnode_free_list_lock);
+
+	uvm_obj_destroy(&vp->v_uobj, true);
+	cv_destroy(&vp->v_cv);
+	pool_cache_put(vcache.pool, node);
+}
+
+/*
  * Get a vnode / fs node pair by key and return it referenced through vpp.
  */
 int
@@ -1208,10 +1213,9 @@ again:
 	error = vfs_busy(mp, NULL);
 	if (error)
 		return error;
-	new_node = pool_cache_get(vcache.pool, PR_WAITOK);
-	new_node->vn_vnode = NULL;
+	new_node = vcache_alloc();
 	new_node->vn_key = vcache_key;
-	vp = vnalloc(NULL);
+	vp = VN_TO_VP(new_node);
 	mutex_enter(&vcache.lock);
 	node = vcache_hash_lookup(&vcache_key, hash);
 	if (node == NULL) {
@@ -1223,10 +1227,9 @@ again:
 
 	/* If another thread beat us inserting this node, retry. */
 	if (node != new_node) {
-		pool_cache_put(vcache.pool, new_node);
 		KASSERT(vp->v_usecount == 1);
 		vp->v_usecount = 0;
-		vnfree(vp);
+		vcache_free(new_node);
 		vfs_unbusy(mp, false, NULL);
 		goto again;
 	}
@@ -1239,10 +1242,9 @@ again:
 		SLIST_REMOVE(&vcache.hashtab[hash & vcache.hashmask],
 		    new_node, vcache_node, vn_hash);
 		mutex_exit(&vcache.lock);
-		pool_cache_put(vcache.pool, new_node);
 		KASSERT(vp->v_usecount == 1);
 		vp->v_usecount = 0;
-		vnfree(vp);
+		vcache_free(new_node);
 		vfs_unbusy(mp, false, NULL);
 		KASSERT(*vpp == NULL);
 		return error;
@@ -1287,20 +1289,18 @@ vcache_new(struct mount *mp, struct vnod
 	error = vfs_busy(mp, NULL);
 	if (error)
 		return error;
-	new_node = pool_cache_get(vcache.pool, PR_WAITOK);
+	new_node = vcache_alloc();
 	new_node->vn_key.vk_mount = mp;
-	new_node->vn_vnode = NULL;
-	vp = vnalloc(NULL);
+	vp = VN_TO_VP(new_node);
 
 	/* Create and load the fs node. */
 	vp->v_iflag |= VI_CHANGING;
 	error = VFS_NEWVNODE(mp, dvp, vp, vap, cred,
 	    &new_node->vn_key.vk_key_len, &new_node->vn_key.vk_key);
 	if (error) {
-		pool_cache_put(vcache.pool, new_node);
 		KASSERT(vp->v_usecount == 1);
 		vp->v_usecount = 0;
-		vnfree(vp);
+		vcache_free(VP_TO_VN(vp));
 		vfs_unbusy(mp, false, NULL);
 		KASSERT(*vpp == NULL);
 		return error;
@@ -1367,8 +1367,7 @@ vcache_rekey_enter(struct mount *mp, str
 	new_vcache_key.vk_key_len = new_key_len;
 	new_hash = vcache_hash(&new_vcache_key);
 
-	new_node = pool_cache_get(vcache.pool, PR_WAITOK);
-	new_node->vn_vnode = NULL;
+	new_node = vcache_alloc();
 	new_node->vn_key = new_vcache_key;
 
 	mutex_enter(&vcache.lock);
@@ -1377,7 +1376,9 @@ vcache_rekey_enter(struct mount *mp, str
 	node = vcache_hash_lookup(&new_vcache_key, new_hash);
 	if (node != NULL) {
 		mutex_exit(&vcache.lock);
-		pool_cache_put(vcache.pool, new_node);
+		KASSERT(VN_TO_VP(new_node)->v_usecount == 1);
+		VN_TO_VP(new_node)->v_usecount = 0;
+		vcache_free(new_node);
 		return EEXIST;
 	}
 	SLIST_INSERT_HEAD(&vcache.hashtab[new_hash & vcache.hashmask],
@@ -1439,7 +1440,9 @@ vcache_rekey_exit(struct mount *mp, stru
 	SLIST_REMOVE(&vcache.hashtab[new_hash & vcache.hashmask],
 	    new_node, vcache_node, vn_hash);
 	mutex_exit(&vcache.lock);
-	pool_cache_put(vcache.pool, new_node);
+	KASSERT(VN_TO_VP(new_node)->v_usecount == 1);
+	VN_TO_VP(new_node)->v_usecount = 0;
+	vcache_free(new_node);
 }
 
 /*
@@ -1463,7 +1466,27 @@ vcache_remove(struct mount *mp, const vo
 	SLIST_REMOVE(&vcache.hashtab[hash & vcache.hashmask],
 	    node, vcache_node, vn_hash);
 	mutex_exit(&vcache.lock);
-	pool_cache_put(vcache.pool, node);
+}
+
+/*
+ * Print a vcache node.
+ */
+void
+vcache_print(vnode_t *vp, const char *prefix, void (*pr)(const char *, ...))
+{
+	int n;
+	const uint8_t *cp;
+	struct vcache_node *node;
+
+	node = VP_TO_VN(vp);
+	n = node->vn_key.vk_key_len;
+	cp = node->vn_key.vk_key;
+
+	(*pr)("%skey(%d)", prefix, n);
+
+	while (n-- > 0)
+		(*pr)(" %02x", *cp++);
+	(*pr)("\n");
 }
 
 /*

Index: src/sys/sys/vnode.h
diff -u src/sys/sys/vnode.h:1.260 src/sys/sys/vnode.h:1.261
--- src/sys/sys/vnode.h:1.260	Thu May 19 14:47:33 2016
+++ src/sys/sys/vnode.h	Thu May 26 11:07:33 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnode.h,v 1.260 2016/05/19 14:47:33 hannken Exp $	*/
+/*	$NetBSD: vnode.h,v 1.261 2016/05/26 11:07:33 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -610,6 +610,8 @@ struct vnode *
 	vnalloc_marker(struct mount *);
 void	vnfree_marker(vnode_t *);
 bool	vnis_marker(vnode_t *);
+void	vcache_print(vnode_t *, const char *,
+    void (*)(const char *, ...) __printflike(1, 2));
 #endif	/* _VFS_VNODE_PRIVATE */
 
 #endif /* _KERNEL */

Reply via email to