aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/dcache.h
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:56 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:28 -0500
commit44a7d7a878c9cbb74f236ea755b25b6b2e26a9a9 (patch)
treed4630a38c0d683a7e1b8823d7971753719b8a54d /include/linux/dcache.h
parentfb045adb99d9b7c562dc7fef834857f78249daa1 (diff)
fs: cache optimise dentry and inode for rcu-walk
Put dentry and inode fields into top of data structure. This allows RCU path traversal to perform an RCU dentry lookup in a path walk by touching only the first 56 bytes of the dentry. We also fit in 8 bytes of inline name in the first 64 bytes, so for short names, only 64 bytes needs to be touched to perform the lookup. We should get rid of the hash->prev pointer from the first 64 bytes, and fit 16 bytes of name in there, which will take care of 81% rather than 32% of the kernel tree. inode is also rearranged so that RCU lookup will only touch a single cacheline in the inode, plus one in the i_ops structure. This is important for directory component lookups in RCU path walking. In the kernel source, directory names average is around 6 chars, so this works. When we reach the last element of the lookup, we need to lock it and take its refcount which requires another cacheline access. Align dentry and inode operations structs, so members will be at predictable offsets and we can group common operations into head of structure. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'include/linux/dcache.h')
-rw-r--r--include/linux/dcache.h36
1 files changed, 19 insertions, 17 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index f4b40a751f09..b1aeda077258 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -82,25 +82,33 @@ full_name_hash(const unsigned char *name, unsigned int len)
82 * large memory footprint increase). 82 * large memory footprint increase).
83 */ 83 */
84#ifdef CONFIG_64BIT 84#ifdef CONFIG_64BIT
85#define DNAME_INLINE_LEN_MIN 32 /* 192 bytes */ 85# define DNAME_INLINE_LEN 32 /* 192 bytes */
86#else 86#else
87#define DNAME_INLINE_LEN_MIN 40 /* 128 bytes */ 87# ifdef CONFIG_SMP
88# define DNAME_INLINE_LEN 36 /* 128 bytes */
89# else
90# define DNAME_INLINE_LEN 40 /* 128 bytes */
91# endif
88#endif 92#endif
89 93
90struct dentry { 94struct dentry {
91 unsigned int d_count; /* protected by d_lock */ 95 /* RCU lookup touched fields */
92 unsigned int d_flags; /* protected by d_lock */ 96 unsigned int d_flags; /* protected by d_lock */
93 spinlock_t d_lock; /* per dentry lock */
94 seqcount_t d_seq; /* per dentry seqlock */ 97 seqcount_t d_seq; /* per dentry seqlock */
95 struct inode *d_inode; /* Where the name belongs to - NULL is
96 * negative */
97 /*
98 * The next three fields are touched by __d_lookup. Place them here
99 * so they all fit in a cache line.
100 */
101 struct hlist_node d_hash; /* lookup hash list */ 98 struct hlist_node d_hash; /* lookup hash list */
102 struct dentry *d_parent; /* parent directory */ 99 struct dentry *d_parent; /* parent directory */
103 struct qstr d_name; 100 struct qstr d_name;
101 struct inode *d_inode; /* Where the name belongs to - NULL is
102 * negative */
103 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
104
105 /* Ref lookup also touches following */
106 unsigned int d_count; /* protected by d_lock */
107 spinlock_t d_lock; /* per dentry lock */
108 const struct dentry_operations *d_op;
109 struct super_block *d_sb; /* The root of the dentry tree */
110 unsigned long d_time; /* used by d_revalidate */
111 void *d_fsdata; /* fs-specific data */
104 112
105 struct list_head d_lru; /* LRU list */ 113 struct list_head d_lru; /* LRU list */
106 /* 114 /*
@@ -112,12 +120,6 @@ struct dentry {
112 } d_u; 120 } d_u;
113 struct list_head d_subdirs; /* our children */ 121 struct list_head d_subdirs; /* our children */
114 struct list_head d_alias; /* inode alias list */ 122 struct list_head d_alias; /* inode alias list */
115 unsigned long d_time; /* used by d_revalidate */
116 const struct dentry_operations *d_op;
117 struct super_block *d_sb; /* The root of the dentry tree */
118 void *d_fsdata; /* fs-specific data */
119
120 unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
121}; 123};
122 124
123/* 125/*
@@ -143,7 +145,7 @@ struct dentry_operations {
143 void (*d_release)(struct dentry *); 145 void (*d_release)(struct dentry *);
144 void (*d_iput)(struct dentry *, struct inode *); 146 void (*d_iput)(struct dentry *, struct inode *);
145 char *(*d_dname)(struct dentry *, char *, int); 147 char *(*d_dname)(struct dentry *, char *, int);
146}; 148} ____cacheline_aligned;
147 149
148/* 150/*
149 * Locking rules for dentry_operations callbacks are to be found in 151 * Locking rules for dentry_operations callbacks are to be found in