drop_caches.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /*
  2. * Implement the manual drop-all-pagecache function
  3. */
  4. #include <linux/kernel.h>
  5. #include <linux/mm.h>
  6. #include <linux/fs.h>
  7. #include <linux/writeback.h>
  8. #include <linux/sysctl.h>
  9. #include <linux/gfp.h>
  10. /* A global variable is a bit ugly, but it keeps the code simple */
  11. int sysctl_drop_caches;
  12. static void drop_pagecache_sb(struct super_block *sb)
  13. {
  14. struct inode *inode;
  15. spin_lock(&inode_lock);
  16. list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
  17. if (inode->i_state & (I_FREEING|I_WILL_FREE))
  18. continue;
  19. invalidate_mapping_pages(inode->i_mapping, 0, -1);
  20. }
  21. spin_unlock(&inode_lock);
  22. }
  23. void drop_pagecache(void)
  24. {
  25. struct super_block *sb;
  26. spin_lock(&sb_lock);
  27. restart:
  28. list_for_each_entry(sb, &super_blocks, s_list) {
  29. sb->s_count++;
  30. spin_unlock(&sb_lock);
  31. down_read(&sb->s_umount);
  32. if (sb->s_root)
  33. drop_pagecache_sb(sb);
  34. up_read(&sb->s_umount);
  35. spin_lock(&sb_lock);
  36. if (__put_super_and_need_restart(sb))
  37. goto restart;
  38. }
  39. spin_unlock(&sb_lock);
  40. }
  41. void drop_slab(void)
  42. {
  43. int nr_objects;
  44. do {
  45. nr_objects = shrink_slab(1000, GFP_KERNEL, 1000);
  46. } while (nr_objects > 10);
  47. }
  48. int drop_caches_sysctl_handler(ctl_table *table, int write,
  49. struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
  50. {
  51. proc_dointvec_minmax(table, write, file, buffer, length, ppos);
  52. if (write) {
  53. if (sysctl_drop_caches & 1)
  54. drop_pagecache();
  55. if (sysctl_drop_caches & 2)
  56. drop_slab();
  57. }
  58. return 0;
  59. }