Commit fd2d8760 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] dentry shrinkage

Rework dentries so that the inline name length is between 31 and 48 bytes.

On SMP P4-compiled x86 each dentry consumes 160 bytes (24 per page).

Here's the histogram of name lengths on all 1.5M files on my workstation:

1:  0%
2:  0%
3:  1%
4:  5%
5:  8%
6:  13%
7:  19%
8:  26%
9:  33%
10:  42%
11:  49%
12:  55%
13:  60%
14:  64%
15:  67%
16:  69%
17:  71%
18:  73%
19:  75%
20:  76%
21:  78%
22:  79%
23:  80%
24:  81%
25:  82%
26:  83%
27:  85%
28:  86%
29:  87%
30:  88%
31:  89%
32:  90%
33:  91%
34:  92%
35:  93%
36:  94%
37:  95%
38:  96%
39:  96%
40:  96%
41:  96%
42:  96%
43:  96%
44:  97%
45:  97%
46:  97%
47:  97%
48:  97%
49:  98%
50:  98%
51:  98%
52:  98%
53:  98%
54:  98%
55:  98%
56:  98%
57:  98%
58:  98%
59:  98%
60:  99%
61:  99%
62:  99%
63:  99%
64:  99%

So on x86 we'll fit 89% of filenames into the inline name.


The patch also removes the NAME_ALLOC_LEN() rounding-up of the storage for the
out-of-line names.  That seems unnecessary.
parent 75fb13cd
......@@ -41,6 +41,13 @@ EXPORT_SYMBOL(dcache_lock);
static kmem_cache_t *dentry_cache;
/*
* The allocation size for each dentry. It is a multiple of 16 bytes. We
* leave the final 32-47 bytes for the inline name.
*/
#define DENTRY_STORAGE (((sizeof(struct dentry)+32) + 15) & ~15)
#define DNAME_INLINE_LEN (DENTRY_STORAGE - sizeof(struct dentry))
/*
* This is the single most critical data structure when it comes
* to the dcache: the hashtable for lookups. Somebody should try
......@@ -665,8 +672,6 @@ static int shrink_dcache_memory(int nr, unsigned int gfp_mask)
return dentry_stat.nr_unused;
}
#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
/**
* d_alloc - allocate a dcache entry
* @parent: parent of entry to allocate
......@@ -688,8 +693,7 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
return NULL;
if (name->len > DNAME_INLINE_LEN-1) {
qstr = kmalloc(sizeof(*qstr) + NAME_ALLOC_LEN(name->len),
GFP_KERNEL);
qstr = kmalloc(sizeof(*qstr) + name->len + 1, GFP_KERNEL);
if (!qstr) {
kmem_cache_free(dentry_cache, dentry);
return NULL;
......@@ -1563,7 +1567,7 @@ static void __init dcache_init(unsigned long mempages)
* of the dcache.
*/
dentry_cache = kmem_cache_create("dentry_cache",
sizeof(struct dentry),
DENTRY_STORAGE,
0,
SLAB_RECLAIM_ACCOUNT,
NULL, NULL);
......
......@@ -74,8 +74,6 @@ full_name_hash(const unsigned char *name, unsigned int len)
return end_name_hash(hash);
}
#define DNAME_INLINE_LEN_MIN 24
struct dcookie_struct;
struct dentry {
......@@ -101,11 +99,9 @@ struct dentry {
struct qstr d_name;
struct hlist_node d_hash; /* lookup hash list */
struct hlist_head * d_bucket; /* lookup hash bucket */
unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
unsigned char d_iname[0]; /* small names */
};
#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
struct dentry_operations {
int (*d_revalidate)(struct dentry *, struct nameidata *);
int (*d_hash) (struct dentry *, struct qstr *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment