b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 2) /*
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 3) * Implement the manual drop-all-pagecache function
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 4) */
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 5)
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 6) #include <linux/kernel.h>
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 7) #include <linux/mm.h>
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 8) #include <linux/fs.h>
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 9) #include <linux/writeback.h>
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 10) #include <linux/sysctl.h>
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 11) #include <linux/gfp.h>
55fa6091d8316 (Dave Chinner 2011-03-22 22:23:40 +1100 12) #include "internal.h"
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 13)
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 14) /* A global variable is a bit ugly, but it keeps the code simple */
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 15) int sysctl_drop_caches;
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 16)
01a05b337a5b6 (Al Viro 2010-03-23 06:06:58 -0400 17) static void drop_pagecache_sb(struct super_block *sb, void *unused)
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 18) {
eccb95cee4f0d (Jan Kara 2008-04-29 00:59:37 -0700 19) struct inode *inode, *toput_inode = NULL;
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 20)
74278da9f70d8 (Dave Chinner 2015-03-04 12:37:22 -0500 21) spin_lock(&sb->s_inode_list_lock);
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 22) list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
250df6ed274d7 (Dave Chinner 2011-03-22 22:23:36 +1100 23) spin_lock(&inode->i_lock);
c27d82f52f75f (Jan Kara 2019-02-01 14:21:23 -0800 24) /*
c27d82f52f75f (Jan Kara 2019-02-01 14:21:23 -0800 25) * We must skip inodes in unusual state. We may also skip
c27d82f52f75f (Jan Kara 2019-02-01 14:21:23 -0800 26) * inodes without pages but we deliberately won't in case
c27d82f52f75f (Jan Kara 2019-02-01 14:21:23 -0800 27) * we need to reschedule to avoid softlockups.
c27d82f52f75f (Jan Kara 2019-02-01 14:21:23 -0800 28) */
250df6ed274d7 (Dave Chinner 2011-03-22 22:23:36 +1100 29) if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
c27d82f52f75f (Jan Kara 2019-02-01 14:21:23 -0800 30) (inode->i_mapping->nrpages == 0 && !need_resched())) {
250df6ed274d7 (Dave Chinner 2011-03-22 22:23:36 +1100 31) spin_unlock(&inode->i_lock);
af065b8a19041 (Jan Kara 2008-04-29 00:59:39 -0700 32) continue;
250df6ed274d7 (Dave Chinner 2011-03-22 22:23:36 +1100 33) }
eccb95cee4f0d (Jan Kara 2008-04-29 00:59:37 -0700 34) __iget(inode);
250df6ed274d7 (Dave Chinner 2011-03-22 22:23:36 +1100 35) spin_unlock(&inode->i_lock);
74278da9f70d8 (Dave Chinner 2015-03-04 12:37:22 -0500 36) spin_unlock(&sb->s_inode_list_lock);
74278da9f70d8 (Dave Chinner 2015-03-04 12:37:22 -0500 37)
286973552f051 (Mike Waychison 2009-06-16 15:32:59 -0700 38) invalidate_mapping_pages(inode->i_mapping, 0, -1);
eccb95cee4f0d (Jan Kara 2008-04-29 00:59:37 -0700 39) iput(toput_inode);
eccb95cee4f0d (Jan Kara 2008-04-29 00:59:37 -0700 40) toput_inode = inode;
74278da9f70d8 (Dave Chinner 2015-03-04 12:37:22 -0500 41)
04646aebd30b9 (Eric Sandeen 2019-12-06 10:54:23 -0600 42) cond_resched();
74278da9f70d8 (Dave Chinner 2015-03-04 12:37:22 -0500 43) spin_lock(&sb->s_inode_list_lock);
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 44) }
74278da9f70d8 (Dave Chinner 2015-03-04 12:37:22 -0500 45) spin_unlock(&sb->s_inode_list_lock);
eccb95cee4f0d (Jan Kara 2008-04-29 00:59:37 -0700 46) iput(toput_inode);
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 47) }
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 48)
1f7e0616cd4f5 (Joe Perches 2014-06-06 14:38:05 -0700 49) int drop_caches_sysctl_handler(struct ctl_table *table, int write,
32927393dc1cc (Christoph Hellwig 2020-04-24 08:43:38 +0200 50) void *buffer, size_t *length, loff_t *ppos)
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 51) {
cb16e95fa2996 (Petr Holasek 2011-03-23 16:43:09 -0700 52) int ret;
cb16e95fa2996 (Petr Holasek 2011-03-23 16:43:09 -0700 53)
cb16e95fa2996 (Petr Holasek 2011-03-23 16:43:09 -0700 54) ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
cb16e95fa2996 (Petr Holasek 2011-03-23 16:43:09 -0700 55) if (ret)
cb16e95fa2996 (Petr Holasek 2011-03-23 16:43:09 -0700 56) return ret;
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 57) if (write) {
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 58) static int stfu;
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 59)
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 60) if (sysctl_drop_caches & 1) {
01a05b337a5b6 (Al Viro 2010-03-23 06:06:58 -0400 61) iterate_supers(drop_pagecache_sb, NULL);
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 62) count_vm_event(DROP_PAGECACHE);
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 63) }
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 64) if (sysctl_drop_caches & 2) {
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 65) drop_slab();
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 66) count_vm_event(DROP_SLAB);
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 67) }
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 68) if (!stfu) {
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 69) pr_info("%s (%d): drop_caches: %d\n",
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 70) current->comm, task_pid_nr(current),
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 71) sysctl_drop_caches);
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 72) }
5509a5d27b971 (Dave Hansen 2014-04-03 14:48:19 -0700 73) stfu |= sysctl_drop_caches & 4;
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 74) }
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 75) return 0;
9d0243bca345d (Andrew Morton 2006-01-08 01:00:39 -0800 76) }