mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
[PATCH] shrink dentry struct
Some long time ago, dentry struct was carefully tuned so that on 32 bits UP, sizeof(struct dentry) was exactly 128, ie a power of 2, and a multiple of memory cache lines. Then RCU was added and dentry struct enlarged by two pointers, with nice results for SMP, but not so good on UP, because breaking the above tuning (128 + 8 = 136 bytes) This patch reverts this unwanted side effect, by using an union (d_u), where d_rcu and d_child are placed so that these two fields can share their memory needs. At the time d_free() is called (and d_rcu is really used), d_child is known to be empty and not touched by the dentry freeing. Lockless lookups only access d_name, d_parent, d_lock, d_op, d_flags (so the previous content of d_child is not needed if said dentry was unhashed but still accessed by a CPU because of RCU constraints) As dentry cache easily contains millions of entries, a size reduction is worth the extra complexity of the ugly C union. Signed-off-by: Eric Dumazet <[email protected]> Cc: Dipankar Sarma <[email protected]> Cc: Maneesh Soni <[email protected]> Cc: Miklos Szeredi <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: Ian Kent <[email protected]> Cc: Paul Jackson <[email protected]> Cc: Al Viro <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Trond Myklebust <[email protected]> Cc: Neil Brown <[email protected]> Cc: James Morris <[email protected]> Cc: Stephen Smalley <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
21b6bf143d
commit
5160ee6fc8
15 changed files with 54 additions and 48 deletions
12
fs/libfs.c
12
fs/libfs.c
|
|
@ -93,16 +93,16 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
|
|||
loff_t n = file->f_pos - 2;
|
||||
|
||||
spin_lock(&dcache_lock);
|
||||
list_del(&cursor->d_child);
|
||||
list_del(&cursor->d_u.d_child);
|
||||
p = file->f_dentry->d_subdirs.next;
|
||||
while (n && p != &file->f_dentry->d_subdirs) {
|
||||
struct dentry *next;
|
||||
next = list_entry(p, struct dentry, d_child);
|
||||
next = list_entry(p, struct dentry, d_u.d_child);
|
||||
if (!d_unhashed(next) && next->d_inode)
|
||||
n--;
|
||||
p = p->next;
|
||||
}
|
||||
list_add_tail(&cursor->d_child, p);
|
||||
list_add_tail(&cursor->d_u.d_child, p);
|
||||
spin_unlock(&dcache_lock);
|
||||
}
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
|||
{
|
||||
struct dentry *dentry = filp->f_dentry;
|
||||
struct dentry *cursor = filp->private_data;
|
||||
struct list_head *p, *q = &cursor->d_child;
|
||||
struct list_head *p, *q = &cursor->d_u.d_child;
|
||||
ino_t ino;
|
||||
int i = filp->f_pos;
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
|||
}
|
||||
for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
|
||||
struct dentry *next;
|
||||
next = list_entry(p, struct dentry, d_child);
|
||||
next = list_entry(p, struct dentry, d_u.d_child);
|
||||
if (d_unhashed(next) || !next->d_inode)
|
||||
continue;
|
||||
|
||||
|
|
@ -261,7 +261,7 @@ int simple_empty(struct dentry *dentry)
|
|||
int ret = 0;
|
||||
|
||||
spin_lock(&dcache_lock);
|
||||
list_for_each_entry(child, &dentry->d_subdirs, d_child)
|
||||
list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
|
||||
if (simple_positive(child))
|
||||
goto out;
|
||||
ret = 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue