From: Maksym Planeta <mcsim.planeta@gmail.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Thomas Knauth <thomas.knauth@gmx.de>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
Maksym Planeta <mcsim.planeta@gmail.com>
Subject: [PATCH] sysctl: Add a feature to drop caches selectively
Date: Tue, 24 Jun 2014 18:10:13 +0200 [thread overview]
Message-ID: <1403626213-7691-1-git-send-email-mcsim.planeta@gmail.com> (raw)
To clean the page cache one can use /proc/sys/vm/drop_caches. But this
drops the whole page cache. In contrast to that sdrop_caches enables
ability to drop the page cache selectively by path string.
Suggested-by: Thomas Knauth <thomas.knauth@gmx.de>
Signed-off-by: Maksym Planeta <mcsim.planeta@gmail.com>
---
Documentation/sysctl/vm.txt | 15 ++++++
fs/Makefile | 2 +-
fs/sdrop_caches.c | 124 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 140 insertions(+), 1 deletion(-)
create mode 100644 fs/sdrop_caches.c
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index bd4b34c..faad01d 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -28,6 +28,7 @@ Currently, these files are in /proc/sys/vm:
- dirty_ratio
- dirty_writeback_centisecs
- drop_caches
+- sdrop_caches
- extfrag_threshold
- hugepages_treat_as_movable
- hugetlb_shm_group
@@ -211,6 +212,20 @@ with your system. To disable them, echo 4 (bit 3) into drop_caches.
==============================================================
+sdrop_caches
+
+Writing to this will cause the kernel to drop clean caches starting from
+specified path.
+
+To free pagecache of a file:
+ echo /home/user/file > /proc/sys/vm/sdrop_caches
+To free pagecache of a directory and all files in it.
+ echo /home/user/directly > /proc/sys/vm/sdrop_caches
+
+Restrictions are the same as for drop_caches.
+
+==============================================================
+
extfrag_threshold
This parameter affects whether the kernel will compact memory or direct
diff --git a/fs/Makefile b/fs/Makefile
index 4030cbf..366c7b9 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -44,7 +44,7 @@ obj-$(CONFIG_FS_MBCACHE) += mbcache.o
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
obj-$(CONFIG_NFS_COMMON) += nfs_common/
obj-$(CONFIG_COREDUMP) += coredump.o
-obj-$(CONFIG_SYSCTL) += drop_caches.o
+obj-$(CONFIG_SYSCTL) += drop_caches.o sdrop_caches.o
obj-$(CONFIG_FHANDLE) += fhandle.o
diff --git a/fs/sdrop_caches.c b/fs/sdrop_caches.c
new file mode 100644
index 0000000..c193655
--- /dev/null
+++ b/fs/sdrop_caches.c
@@ -0,0 +1,124 @@
+/*
+ * Implement the manual selective drop pagecache function
+ */
+
+#include <linux/module.h>
+
+
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <linux/uaccess.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/writeback.h>
+#include <linux/sysctl.h>
+#include <linux/gfp.h>
+#include <linux/limits.h>
+#include <linux/namei.h>
+
+static void clean_mapping(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+
+ if (!inode)
+ return;
+
+ if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
+ (inode->i_mapping->nrpages == 0)) {
+ return;
+ }
+
+ invalidate_mapping_pages(inode->i_mapping, 0, -1);
+}
+
+static void clean_all_dentries_locked(struct dentry *dentry)
+{
+ struct dentry *child;
+
+ list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
+ clean_all_dentries_locked(child);
+ }
+
+ clean_mapping(dentry);
+}
+
+static void clean_all_dentries(struct dentry *dentry)
+{
+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
+ clean_all_dentries_locked(dentry);
+ spin_unlock(&dentry->d_lock);
+}
+
+static int drop_pagecache(const char * __user filename)
+{
+ unsigned int lookup_flags = LOOKUP_FOLLOW;
+ struct path path;
+ int error;
+
+retry:
+ error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
+ if (!error) {
+ /* clean */
+ clean_all_dentries(path.dentry);
+ }
+ if (retry_estale(error, lookup_flags)) {
+ lookup_flags |= LOOKUP_REVAL;
+ goto retry;
+ }
+ return error;
+}
+
+static int sdrop_ctl_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ char __user *pathname = buffer + *lenp - 1;
+
+ put_user('\0', pathname);
+
+ if (!write)
+ return 0;
+
+ return drop_pagecache(buffer);
+}
+
+static struct ctl_path vm_path[] = { { .procname = "vm", }, { } };
+static struct ctl_table sdrop_ctl_table[] = {
+ {
+ .procname = "sdrop_caches",
+ .mode = 0644,
+ .proc_handler = sdrop_ctl_handler,
+ },
+ { }
+};
+
+static struct ctl_table_header *sdrop_proc_entry;
+
+/* Init function called on module entry */
+int sdrop_init(void)
+{
+ int ret = 0;
+
+ sdrop_proc_entry = register_sysctl_paths(vm_path, sdrop_ctl_table);
+
+ if (sdrop_proc_entry == NULL) {
+ ret = -ENOMEM;
+ pr_err("sdrop_caches: Couldn't create proc entry\n");
+ }
+
+ return ret;
+}
+
+/* Cleanup function called on module exit */
+void sdrop_cleanup(void)
+{
+ unregister_sysctl_table(sdrop_proc_entry);
+}
+
+module_init(sdrop_init);
+module_exit(sdrop_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Selective pagecache drop module");
+MODULE_AUTHOR("Maksym Planeta");
--
2.0.0
next reply other threads:[~2014-06-24 16:10 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-24 16:10 Maksym Planeta [this message]
2014-06-24 21:59 ` [PATCH] sysctl: Add a feature to drop caches selectively David Rientjes
2014-06-25 6:25 ` Artem Bityutskiy
2014-06-25 8:25 ` Thomas Knauth
2014-06-25 9:56 ` Artem Bityutskiy
2014-06-25 13:23 ` Thomas Knauth
2014-06-25 13:30 ` Artem Bityutskiy
2014-06-25 13:42 ` Artem Bityutskiy
2014-06-26 9:30 ` Maksym Planeta
2014-06-25 10:03 ` Artem Bityutskiy
2014-06-25 13:19 ` Thomas Knauth
2014-06-25 22:15 ` Pavel Machek
2014-06-26 1:06 ` Dave Chinner
2014-06-26 6:13 ` Artem Bityutskiy
2014-06-26 10:36 ` Bernd Schubert
2014-06-26 11:31 ` Artem Bityutskiy
2014-06-26 11:57 ` Lukáš Czerner
2014-06-26 12:10 ` Bernd Schubert
2014-06-27 2:55 ` Dave Chinner
2014-06-27 8:58 ` Bernd Schubert
2014-06-27 8:41 ` Matthias Schniedermeyer
2014-06-27 9:04 ` Lukáš Czerner
2014-06-27 9:08 ` Artem Bityutskiy
2014-06-27 9:09 ` Bityutskiy, Artem
2014-06-27 2:48 ` Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1403626213-7691-1-git-send-email-mcsim.planeta@gmail.com \
--to=mcsim.planeta@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=thomas.knauth@gmx.de \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).