6

My earlier question apparently had a wrong premise. I thought file system meta data was cached in the inode and dentry cache, but apparently not.

When I do:

# time find . > /dev/null

real    10m4.435s
user    0m3.904s
sys     0m15.505s

# time find . > /dev/null

real    0m5.681s
user    0m1.400s
sys     0m4.224s

You can see the second run is a lot faster. But, it reverts back to 10 minutes when I free the page cache only:

echo 1 > /proc/sys/vm/drop_caches

Slabtop still shows a big cache after dropping those caches:

   OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
1758897 1758713  99%    0.19K  83757       21    335028K dentry
1216908 1211861  99%    0.76K  57948       21    927168K ext3_inode_cache

I don't get how that works anyway, because after dropping all caches (echo 3 > /proc/sys/vm/drop_caches), slabtop still reports a big cache size:

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
1288434 955168  74%    0.19K  61354       21    245416K dentry                 
1216908 1211861  99%    0.76K  57948       21    927168K ext3_inode_cache

So, is the data obtained by find stored in the page cache? I would like to store that data in cache permanently, to not have disk IO because of daily backups, but if it's stored in the page_cache, I can't use vfs_cache_pressure to control it.

Edit:

When I do a find and echo 2 to drop_caches (which would drop the dentry and inode cache), find is still fast, and /proc/meminfo still shows slab use:

# time find . > /dev/null    
real    8m11.918s
user    0m3.888s
sys     0m15.313s

# echo 2 > /proc/sys/vm/drop_caches

# time find . > /dev/null
real    0m8.883s
user    0m1.540s
sys     0m4.724s

And meminfo:

# cat /proc/meminfo |grep -i "^cache\|Slab"
Cached:           425224 kB
Slab:             891648 kB

echo 2 > /proc/sys/vm/drop_caches

# cat /proc/meminfo |grep -i "^cache\|Slab"
Cached:           333740 kB
Slab:             793428 kB

It's ubuntu 12.04 on ext3.

migrated from serverfault.com Apr 10 '15 at 21:44

This question came from our site for system and network administrators.

5

This is because your test is flawed. Running find . merely calls getdents() on the directory tree. A directory in this case is just a file that contains directory entries and is thus stored in page cache. Note you do nothing to actually access the files you are attempting to cache in this manner.

Your test is basically caching all the directories in the filesystem tree and nothing else.

Try your test giving find a harder task to do. Such as forcing it to call lstat for every file and you'll see a different behaviour.

In my test there are a million files in this directory.

[root@home test]# echo 3 >/proc/sys/vm/drop_caches 
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null

real    0m16.443s
user    0m2.123s
sys 0m9.320s
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null

real    0m2.704s
user    0m1.224s
sys 0m1.479s
[root@home test]# echo 1 >/proc/sys/vm/drop_caches 
[root@home test]# time find ./tmp -printf "%p %c\n" >/dev/null

real    0m3.791s
user    0m1.359s
sys 0m1.756s

Note in the last test it takes slightly longer, I imagine this is directly related to all the reading of the directory 'file' itself rather than because the dentry and inode cache does not exist.

  • So is there a way to keep the directory entries in cache over file contents? That would help with scanning the file system for each daily backup. – Halfgaar Apr 9 '15 at 13:00
  • Running find with a "%c" in it as above may help. Note even under the best circumstances you can only guarantee half of the data you stat has a chance of staying in the cache. You'd have to scan the same data set about 3 times to try to get it into 'active' cache too. – Matthew Ife Apr 9 '15 at 16:28
  • Why does scanning three times help? I thought the way the Linux cache works, is just FIFO. – Halfgaar Apr 10 '15 at 7:59
  • Pages need to be referenced at least twice to go into the 'active' file cache. Those in active are not eligible for eviction. Only half of the cache remains active at any point in time. – Matthew Ife Apr 10 '15 at 17:06
0

On my system (CentOS 7 x86_64), find . /usr/ seems to load i/dentry cache only, and not pagecache.

Let's start form a "clean" state:

echo 3 > /proc/sys/vm/drop_caches

cat /proc/meminfo | grep -i "^cache\|Slab"
Cached:           280432 kB
Slab:              66632 kB

Now, time find . /usr/ > /dev/null 2>/dev/null

real    0m5.126s
user    0m0.580s
sys     0m2.939s

cat /proc/meminfo | grep -i "^cache\|Slab"
Cached:           283308 kB
Slab:             288656 kB

Only Slab increased in size. Now, let's drop the i/dcache:

echo 2 > /proc/sys/vm/drop_caches

cat /proc/meminfo | grep -i "^cache\|Slab"
Cached:           282704 kB
Slab:              66428 kB

Slab size decrease drastically. time find . /usr/ > /dev/null 2>/dev/null give

real    0m5.122s
user    0m0.624s
sys     0m2.905s

Same as above. Dropping the pagecache only with

echo 1 > /proc/sys/vm/drop_caches

time find . /usr/ > /dev/null 2>/dev/null
real    0m0.848s
user    0m0.256s
sys     0m0.575s

As you can see, dropping the pagecache only does not affect find speed, which remain much faster than before.

  • See my edit. When I echo 2 to drop_caches, find it still fast. I wonder what you'll see with bigger directories. The difference between 5 and 1 second isn't big to begin with. – Halfgaar Apr 8 '15 at 16:09
  • I have an SSD, so even uncached access is quite fast. I can try with bigger directories, if you want. – shodanshok Apr 8 '15 at 17:13
  • Hmm. When I set vfs_cache_pressure back to the default 100, the behavior is like yours. So drop_caches behaves differently when you have a different cache pressure...? Weird. – Halfgaar Apr 9 '15 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.