linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: David Chinner <dgc@sgi.com>
From: gnb@sgi.com
To: Bharata B Rao <bharata@in.ibm.com>
Cc: Dipankar Sarma <dipankar@in.ibm.com>, linux-mm@kvack.org, gnb@sgi.com
Subject: [PATCH] dcache: separate slab for directory dentries
Date: Thu, 6 Oct 2005 16:27:39 +1000	[thread overview]
Message-ID: <20051006062739.GP9519161@melbourne.sgi.com> (raw)
In-Reply-To: <20050913215932.GA1654338@melbourne.sgi.com>

Separate out directory dentries into a separate slab so that
(potentially) longer lived dentries are clustered together rather
than sparsely distributed around the dentry slab cache.

Originally written for 2.6.5 by Greg Banks.

Signed-off-by: Greg Banks (gnb@sgi.com)
Signed-off-by: Dave Chinner (dgc@sgi.com)
---

Reference: http://marc.theaimsgroup.com/?l=linux-mm&m=112664896809759&w=2

 fs/dcache.c            |  100 ++++++++++++++++++++++++++++++++++++++++++++-----
 include/linux/dcache.h |    1 
 2 files changed, 91 insertions(+), 10 deletions(-)

--- 2.6.x-xfs.orig/include/linux/dcache.h	2005-10-06 12:41:12.000000000 +1000
+++ 2.6.x-xfs/include/linux/dcache.h	2005-10-06 10:51:31.825645594 +1000
@@ -155,6 +155,7 @@
 
 #define DCACHE_REFERENCED	0x0008  /* Recently used, don't discard. */
 #define DCACHE_UNHASHED		0x0010	
+#define DCACHE_DIRSLAB    	0x0040  /* allocated in the dir memcache */
 
 extern spinlock_t dcache_lock;
 
--- 2.6.x-xfs.orig/fs/dcache.c	2005-10-06 12:41:12.000000000 +1000
+++ 2.6.x-xfs/fs/dcache.c	2005-10-06 11:02:12.986649700 +1000
@@ -45,6 +45,7 @@
 EXPORT_SYMBOL(dcache_lock);
 
 static kmem_cache_t *dentry_cache; 
+static kmem_cache_t *dentry_dir_cache; 
 
 #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
 
@@ -75,7 +76,8 @@
 
 	if (dname_external(dentry))
 		kfree(dentry->d_name.name);
-	kmem_cache_free(dentry_cache, dentry); 
+	kmem_cache_free((dentry->d_flags & DCACHE_DIRSLAB) ? 
+	    	    	    dentry_dir_cache : dentry_cache, dentry);
 }
 
 /*
@@ -707,7 +709,7 @@
 }
 
 /**
- * d_alloc	-	allocate a dcache entry
+ * __d_alloc	-	allocate a dcache entry
  * @parent: parent of entry to allocate
  * @name: qstr of the name
  *
@@ -716,19 +718,22 @@
  * copied and the copy passed in may be reused after this call.
  */
  
-struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
+static struct dentry * __d_alloc(struct dentry * parent,
+				 const struct qstr *name, int flags)
 {
 	struct dentry *dentry;
 	char *dname;
+	kmem_cache_t *cache;
 
-	dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 
+	cache = (flags & DCACHE_DIRSLAB) ? dentry_dir_cache : dentry_cache;
+	dentry = kmem_cache_alloc(cache, GFP_KERNEL); 
 	if (!dentry)
 		return NULL;
 
 	if (name->len > DNAME_INLINE_LEN-1) {
 		dname = kmalloc(name->len + 1, GFP_KERNEL);
 		if (!dname) {
-			kmem_cache_free(dentry_cache, dentry); 
+			kmem_cache_free(cache, dentry); 
 			return NULL;
 		}
 	} else  {
@@ -742,7 +747,7 @@
 	dname[name->len] = 0;
 
 	atomic_set(&dentry->d_count, 1);
-	dentry->d_flags = DCACHE_UNHASHED;
+	dentry->d_flags = (DCACHE_UNHASHED | flags);
 	spin_lock_init(&dentry->d_lock);
 	dentry->d_inode = NULL;
 	dentry->d_parent = NULL;
@@ -782,6 +787,69 @@
 	return d_alloc(parent, &q);
 }
 
+struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
+{
+	return __d_alloc(parent, name, 0);
+}
+
+/*
+ * Allocate a new dentry which will be suitable for the given inode
+ */
+static struct dentry * d_alloc_for_inode(struct dentry * parent,
+					 const struct qstr *name,
+					 struct inode *inode)
+{
+	int flags = 0;
+	
+	if (inode && S_ISDIR(inode->i_mode))
+		flags |= DCACHE_DIRSLAB;
+
+	return __d_alloc(parent, name, flags);
+}
+
+/*
+ * If the given dentry is not suitable for the inode, reallocate
+ * it, copy across the dentry's data and return the new one.  Only
+ * useful when the dentry has not yet been attached to inode or
+ * hashed, which is why it's a lot simpler than d_move().  Returns
+ * NULL if the dentry is suitable,  Called with dcache_lock, drops
+ * and regains.
+ */
+static struct dentry * d_realloc_for_inode(struct dentry * dentry,
+					   struct inode *inode)
+{
+	int flags = 0;
+	struct dentry *new;
+	struct dentry *parent;
+	
+	BUG_ON(dentry == NULL);
+	BUG_ON(dentry->d_inode != NULL);
+	BUG_ON(inode == NULL);
+	BUG_ON(dentry->d_parent == NULL || dentry->d_parent == dentry);
+
+	if (S_ISDIR(inode->i_mode))
+		flags |= DCACHE_DIRSLAB;
+	if ((flags & DCACHE_DIRSLAB) == (dentry->d_flags & DCACHE_DIRSLAB))
+		return NULL;	/* dentry is suitable */
+
+	parent = dentry->d_parent;
+	list_del_init(&dentry->d_child);
+
+	spin_unlock(&dcache_lock);
+	
+	new = __d_alloc(parent, &dentry->d_name, dentry->d_flags | flags);
+
+	spin_lock(&dcache_lock);
+
+	BUG_ON(new == NULL);	/* TODO */
+	if (new) {
+//		new->d_op = dentry->d_op;
+//		new->d_fsdata = dentry->d_fsdata;
+	}
+	
+	return new;
+}
+
 /**
  * d_instantiate - fill in inode information for a dentry
  * @entry: dentry to complete
@@ -872,7 +940,7 @@
 	if (root_inode) {
 		static const struct qstr name = { .name = "/", .len = 1 };
 
-		res = d_alloc(NULL, &name);
+		res = d_alloc_for_inode(NULL, &name, root_inode);
 		if (res) {
 			res->d_sb = root_inode->i_sb;
 			res->d_parent = res;
@@ -921,7 +989,7 @@
 		return res;
 	}
 
-	tmp = d_alloc(NULL, &anonstring);
+	tmp = d_alloc_for_inode(NULL, &anonstring, inode);
 	if (!tmp)
 		return NULL;
 
@@ -987,6 +1055,8 @@
 			iput(inode);
 		} else {
 			/* d_instantiate takes dcache_lock, so we do it by hand */
+			if ((new = d_realloc_for_inode(dentry, inode)))
+				dentry = new;
 			list_add(&dentry->d_alias, &inode->i_dentry);
 			dentry->d_inode = inode;
 			spin_unlock(&dcache_lock);
@@ -1014,7 +1084,7 @@
  * To avoid races with d_move while rename is happening, d_lock is used.
  *
  * Overflows in memcmp(), while d_move, are avoided by keeping the length
- * and name pointer in one structure pointed by d_qstr.
+ * and name pointer in one structure pointed by d_name.
  *
  * rcu_read_lock() and rcu_read_unlock() are used to disable preemption while
  * lookup is going on.
@@ -1121,7 +1191,8 @@
 	struct hlist_node *lhp;
 
 	/* Check whether the ptr might be valid at all.. */
-	if (!kmem_ptr_validate(dentry_cache, dentry))
+	if (!kmem_ptr_validate(dentry_cache, dentry) &&
+	    !kmem_ptr_validate(dentry_dir_cache, dentry))
 		goto out;
 
 	if (dentry->d_parent != dparent)
@@ -1687,6 +1758,15 @@
 					 SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
 					 NULL, NULL);
 	
+	dentry_dir_cache = kmem_cache_create("dentry_dir_cache",
+					 sizeof(struct dentry),
+					 0,
+					 SLAB_RECLAIM_ACCOUNT,
+					 NULL, NULL);
+	if (!dentry_dir_cache)
+		panic("Cannot create dentry dir cache");
+	
+
 	set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory);
 
 	/* Hash may have been set up in dcache_init_early */

-- 
Dave Chinner
R&D Software Enginner
SGI Australian Software Group

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2005-10-06  6:27 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-11 10:57 VM balancing issues on 2.6.13: dentry cache not getting shrunk enough Theodore Ts'o
2005-09-11 12:00 ` Dipankar Sarma
2005-09-12  3:16   ` Theodore Ts'o
2005-09-12  6:16     ` Martin J. Bligh
2005-09-12 12:53       ` Bharata B Rao
2005-09-13  8:47     ` Bharata B Rao
2005-09-13 21:59       ` David Chinner
2005-09-14  9:01         ` Andi Kleen
2005-09-14  9:16           ` Manfred Spraul
2005-09-14  9:43             ` Andrew Morton
2005-09-14  9:52               ` Dipankar Sarma
2005-09-14 22:44               ` Theodore Ts'o
2005-09-14  9:35           ` Andrew Morton
2005-09-14 13:57           ` Martin J. Bligh
2005-09-14 15:37             ` Sonny Rao
2005-09-15  7:21             ` Helge Hafting
2005-09-14 22:48           ` David Chinner
2005-09-14 15:48         ` Sonny Rao
2005-09-14 22:02           ` David Chinner
2005-09-14 22:40             ` Sonny Rao
2005-09-15  1:14               ` David Chinner
2005-10-06  6:27         ` David Chinner, gnb [this message]
2005-10-06 12:28           ` [PATCH] dcache: separate slab for directory dentries Dave Kleikamp
2005-10-07  3:54             ` Greg Banks
2005-10-07 13:00               ` Dave Kleikamp
2005-09-14 21:34       ` VM balancing issues on 2.6.13: dentry cache not getting shrunk enough Marcelo Tosatti
2005-09-14 21:43         ` Dipankar Sarma
2005-09-15  4:28         ` Bharata B Rao
2005-09-14 23:08       ` Marcelo Tosatti
2005-09-15  9:39         ` Bharata B Rao
2005-09-15 13:29           ` Marcelo Tosatti
2005-10-02 16:32             ` Bharata B Rao
2005-10-02 20:06               ` Marcelo
2005-10-04 13:36                 ` shrinkable cache statistics [was Re: VM balancing issues on 2.6.13: dentry cache not getting shrunk enough] Bharata B Rao
2005-10-05 21:25                   ` Marcelo Tosatti
2005-10-07  8:12                     ` Bharata B Rao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20051006062739.GP9519161@melbourne.sgi.com \
    --to=dgc@sgi.com \
    --cc=bharata@in.ibm.com \
    --cc=dipankar@in.ibm.com \
    --cc=gnb@sgi.com \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox