Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
drop_caches.c
Go to the documentation of this file.
1 /*
2  * Implement the manual drop-all-pagecache function
3  */
4 
5 #include <linux/kernel.h>
6 #include <linux/mm.h>
7 #include <linux/fs.h>
8 #include <linux/writeback.h>
9 #include <linux/sysctl.h>
10 #include <linux/gfp.h>
11 #include "internal.h"
12 
13 /* A global variable is a bit ugly, but it keeps the code simple */
15 
16 static void drop_pagecache_sb(struct super_block *sb, void *unused)
17 {
18  struct inode *inode, *toput_inode = NULL;
19 
20  spin_lock(&inode_sb_list_lock);
21  list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
22  spin_lock(&inode->i_lock);
23  if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
24  (inode->i_mapping->nrpages == 0)) {
25  spin_unlock(&inode->i_lock);
26  continue;
27  }
28  __iget(inode);
29  spin_unlock(&inode->i_lock);
30  spin_unlock(&inode_sb_list_lock);
31  invalidate_mapping_pages(inode->i_mapping, 0, -1);
32  iput(toput_inode);
33  toput_inode = inode;
34  spin_lock(&inode_sb_list_lock);
35  }
36  spin_unlock(&inode_sb_list_lock);
37  iput(toput_inode);
38 }
39 
40 static void drop_slab(void)
41 {
42  int nr_objects;
43  struct shrink_control shrink = {
44  .gfp_mask = GFP_KERNEL,
45  };
46 
47  do {
48  nr_objects = shrink_slab(&shrink, 1000, 1000);
49  } while (nr_objects > 10);
50 }
51 
53  void __user *buffer, size_t *length, loff_t *ppos)
54 {
55  int ret;
56 
57  ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
58  if (ret)
59  return ret;
60  if (write) {
61  if (sysctl_drop_caches & 1)
62  iterate_supers(drop_pagecache_sb, NULL);
63  if (sysctl_drop_caches & 2)
64  drop_slab();
65  }
66  return 0;
67 }