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>
next prev 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