diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-06 22:45:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-06 22:53:23 -0700 |
commit | 3ddcd0569cd68f00f3beae9a7959b72918bb91f4 (patch) | |
tree | 3f7c591316560b1c22e2cc0700fbcd29aa3fbd7f /fs/stat.c | |
parent | 830c0f0edca67403d361fe976a25b17356c11f19 (diff) | |
download | lwn-3ddcd0569cd68f00f3beae9a7959b72918bb91f4.tar.gz lwn-3ddcd0569cd68f00f3beae9a7959b72918bb91f4.zip |
vfs: optimize inode cache access patterns
The inode structure layout is largely random, and some of the vfs paths
really do care. The path lookup in particular is already quite D$
intensive, and profiles show that accessing the 'inode->i_op->xyz'
fields is quite costly.
We already optimized the dcache to not unnecessarily load the d_op
structure for members that are often NULL using the DCACHE_OP_xyz bits
in dentry->d_flags, and this does something very similar for the inode
ops that are used during pathname lookup.
It also re-orders the fields so that the fields accessed by 'stat' are
together at the beginning of the inode structure, and roughly in the
order accessed.
The effect of this seems to be in the 1-2% range for an empty kernel
"make -j" run (which is fairly kernel-intensive, mostly in filename
lookup), so it's visible. The numbers are fairly noisy, though, and
likely depend a lot on exact microarchitecture. So there's more tuning
to be done.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/stat.c')
-rw-r--r-- | fs/stat.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/stat.c b/fs/stat.c index 961039121cb8..ba5316ffac61 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -27,12 +27,12 @@ void generic_fillattr(struct inode *inode, struct kstat *stat) stat->uid = inode->i_uid; stat->gid = inode->i_gid; stat->rdev = inode->i_rdev; + stat->size = i_size_read(inode); stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; stat->ctime = inode->i_ctime; - stat->size = i_size_read(inode); - stat->blocks = inode->i_blocks; stat->blksize = (1 << inode->i_blkbits); + stat->blocks = inode->i_blocks; } EXPORT_SYMBOL(generic_fillattr); |