aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/fs.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/fs.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/fs.h')
-rw-r--r--include/linux/fs.h42
1 files changed, 23 insertions, 19 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ea202fff44f8..a04aa96acb71 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -733,6 +733,20 @@ struct posix_acl;
733#define ACL_NOT_CACHED ((void *)(-1)) 733#define ACL_NOT_CACHED ((void *)(-1))
734 734
735struct inode { 735struct inode {
736 /* RCU path lookup touches following: */
737 umode_t i_mode;
738 uid_t i_uid;
739 gid_t i_gid;
740 const struct inode_operations *i_op;
741 struct super_block *i_sb;
742
743 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
744 unsigned int i_flags;
745 struct mutex i_mutex;
746
747 unsigned long i_state;
748 unsigned long dirtied_when; /* jiffies of first dirtying */
749
736 struct hlist_node i_hash; 750 struct hlist_node i_hash;
737 struct list_head i_wb_list; /* backing dev IO list */ 751 struct list_head i_wb_list; /* backing dev IO list */
738 struct list_head i_lru; /* inode LRU list */ 752 struct list_head i_lru; /* inode LRU list */
@@ -744,8 +758,6 @@ struct inode {
744 unsigned long i_ino; 758 unsigned long i_ino;
745 atomic_t i_count; 759 atomic_t i_count;
746 unsigned int i_nlink; 760 unsigned int i_nlink;
747 uid_t i_uid;
748 gid_t i_gid;
749 dev_t i_rdev; 761 dev_t i_rdev;
750 unsigned int i_blkbits; 762 unsigned int i_blkbits;
751 u64 i_version; 763 u64 i_version;
@@ -758,13 +770,8 @@ struct inode {
758 struct timespec i_ctime; 770 struct timespec i_ctime;
759 blkcnt_t i_blocks; 771 blkcnt_t i_blocks;
760 unsigned short i_bytes; 772 unsigned short i_bytes;
761 umode_t i_mode;
762 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
763 struct mutex i_mutex;
764 struct rw_semaphore i_alloc_sem; 773 struct rw_semaphore i_alloc_sem;
765 const struct inode_operations *i_op;
766 const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ 774 const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
767 struct super_block *i_sb;
768 struct file_lock *i_flock; 775 struct file_lock *i_flock;
769 struct address_space *i_mapping; 776 struct address_space *i_mapping;
770 struct address_space i_data; 777 struct address_space i_data;
@@ -785,11 +792,6 @@ struct inode {
785 struct hlist_head i_fsnotify_marks; 792 struct hlist_head i_fsnotify_marks;
786#endif 793#endif
787 794
788 unsigned long i_state;
789 unsigned long dirtied_when; /* jiffies of first dirtying */
790
791 unsigned int i_flags;
792
793#ifdef CONFIG_IMA 795#ifdef CONFIG_IMA
794 /* protected by i_lock */ 796 /* protected by i_lock */
795 unsigned int i_readcount; /* struct files open RO */ 797 unsigned int i_readcount; /* struct files open RO */
@@ -1549,8 +1551,15 @@ struct file_operations {
1549}; 1551};
1550 1552
1551struct inode_operations { 1553struct inode_operations {
1552 int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
1553 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); 1554 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
1555 void * (*follow_link) (struct dentry *, struct nameidata *);
1556 int (*permission) (struct inode *, int);
1557 int (*check_acl)(struct inode *, int);
1558
1559 int (*readlink) (struct dentry *, char __user *,int);
1560 void (*put_link) (struct dentry *, struct nameidata *, void *);
1561
1562 int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
1554 int (*link) (struct dentry *,struct inode *,struct dentry *); 1563 int (*link) (struct dentry *,struct inode *,struct dentry *);
1555 int (*unlink) (struct inode *,struct dentry *); 1564 int (*unlink) (struct inode *,struct dentry *);
1556 int (*symlink) (struct inode *,struct dentry *,const char *); 1565 int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -1559,12 +1568,7 @@ struct inode_operations {
1559 int (*mknod) (struct inode *,struct dentry *,int,dev_t); 1568 int (*mknod) (struct inode *,struct dentry *,int,dev_t);
1560 int (*rename) (struct inode *, struct dentry *, 1569 int (*rename) (struct inode *, struct dentry *,
1561 struct inode *, struct dentry *); 1570 struct inode *, struct dentry *);
1562 int (*readlink) (struct dentry *, char __user *,int);
1563 void * (*follow_link) (struct dentry *, struct nameidata *);
1564 void (*put_link) (struct dentry *, struct nameidata *, void *);
1565 void (*truncate) (struct inode *); 1571 void (*truncate) (struct inode *);
1566 int (*permission) (struct inode *, int);
1567 int (*check_acl)(struct inode *, int);
1568 int (*setattr) (struct dentry *, struct iattr *); 1572 int (*setattr) (struct dentry *, struct iattr *);
1569 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); 1573 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
1570 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); 1574 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1576,7 +1580,7 @@ struct inode_operations {
1576 loff_t len); 1580 loff_t len);
1577 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, 1581 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
1578 u64 len); 1582 u64 len);
1579}; 1583} ____cacheline_aligned;
1580 1584
1581struct seq_file; 1585struct seq_file;
1582 1586