From patchwork Mon Jan 7 13:02:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Whitchurch X-Patchwork-Id: 10750553 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DC99A14DE for ; Mon, 7 Jan 2019 13:03:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB7412899D for ; Mon, 7 Jan 2019 13:03:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBBF2289EC; Mon, 7 Jan 2019 13:03:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BF1432899D for ; Mon, 7 Jan 2019 13:03:05 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id AB5D98E0025; Mon, 7 Jan 2019 08:03:04 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A65C98E0001; Mon, 7 Jan 2019 08:03:04 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 956868E0025; Mon, 7 Jan 2019 08:03:04 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-lj1-f200.google.com (mail-lj1-f200.google.com [209.85.208.200]) by kanga.kvack.org (Postfix) with ESMTP id 221228E0001 for ; Mon, 7 Jan 2019 08:03:04 -0500 (EST) Received: by mail-lj1-f200.google.com with SMTP id 2-v6so45513ljs.15 for ; Mon, 07 Jan 2019 05:03:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:mime-version:content-transfer-encoding; bh=kvlFCVAb2EPdThJub5Zq9QFaWOAnWPby5VtZAUdJQfM=; b=dFRpVD8Ohjv8y0inUOXWo7NptlFV0q3uydO9etPRxoMvHzjRJhteFjsu9eFpvKZH/v 7GZKlWSsGOn/bsql0KyE0goNxLVlICL8xtm+BEcVtAOXxrLFgMNOVMfHWeOAaTqq0O1R 7JAtoQD//bouLfoEQ+ld9yyZMYPr+/nTjFv8nT9k/JMW7T0XYR3MTIwyuEQOZDVWvKwK ZD1tnoIUH/luGGgtJAE2/60aGmAj67EefUArVJVNjbxNSUzoAhUaLpcY52+D/7iQTt9Y Vnj3GIT0nn72Tl2t/tCmHre+WVnbdid4teQvNLqP8EQ+PPveS+Zm1+OiVb6AwjCnT8T9 qNGg== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of vincent.whitchurch@axis.com designates 195.60.68.11 as permitted sender) smtp.mailfrom=vincent.whitchurch@axis.com X-Gm-Message-State: AJcUukcOuUtbJDQfRs34X/gtv5nQQ3ljjhDR96Yk+NEMyLxlWUWxHEVm prswqnHurb6Kg3gpcwlsrMlpAMdBLdJMv/HyaAAuVCtARljWl1INJD0jjbWZ4XUkS6rTMzEP2PL KddUqV0B6AKauNrrxeSOW8fE/yHNT7F2+Qj9vZ2/PClmbs36UE/l/lNtaUurd4q5w7g== X-Received: by 2002:a19:645b:: with SMTP id b27mr16737240lfj.14.1546866183470; Mon, 07 Jan 2019 05:03:03 -0800 (PST) X-Google-Smtp-Source: ALg8bN4gFKlo3qKC74geyEQg/FLwgPtplUglSj+WvQ5OHhNEwGdkCp97AN+wkoYK/rLwnFkwpHDD X-Received: by 2002:a19:645b:: with SMTP id b27mr16737198lfj.14.1546866182070; Mon, 07 Jan 2019 05:03:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546866182; cv=none; d=google.com; s=arc-20160816; b=HJ8BYEpm/5EIpwchzlk7DyjziYYnM1p+W8BCvWVvMhoNdUq1fCl40Fa58zdxg945wI rf9erfNr/XCSgY/dWvQ3PhlsGH444B0CBYdCAOJFSSBViIUe3BVmwMnLhAsOwojeDYh0 AevhUSLDl/2NKL7LDu30bkbp3KmMHNmE1X0PAMkXcJ7cWUnIxiiLAmUo/2ZqHFNq3ipG o/inV51aNUA1D0+zXtGc1QQ9tJiqcHFTs2WUdp+cp1kV7uYTt9BZgOPpBHUif44jUNQT zM2MkZIXLleJWd3BRt3D/4s61x9K65Hr8AJeVi/APRmpvpL9XS8ryduccfp1JdHg83sD H1QQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from; bh=kvlFCVAb2EPdThJub5Zq9QFaWOAnWPby5VtZAUdJQfM=; b=i7Wb/k1G1/fSY/0BQbdeSfBQOpD2/I0caUw2Pa5LHDQSEQ2DB7lI+5J/NxpNSdbaok vx2GhmEHMV34Iuzfvqsf9EVsSICka2o/BhLQ41PJ4ob30BqcalciEFzcQQSHrVvUSoxK wZiLcSNM+4pPwcmnWUNhh4Y2VtIAb3GAfX3/L6/W7fEUgtGr4pMAHe9BrhNBizkV5P7Y 2CM0MzbAnqgJaBEA5pWb4MNAPrpzbPBRGANUL6feseJ3yglIsoIfSm6F/vAhVZYXmv6P 6OLIIVolGJwZZ98Wxf+YmrAZfxI25opk9YogLBrf7ygur95GzrS0/SJ7mKfceoOjKfNV H4fw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of vincent.whitchurch@axis.com designates 195.60.68.11 as permitted sender) smtp.mailfrom=vincent.whitchurch@axis.com Received: from bastet.se.axis.com (bastet.se.axis.com. [195.60.68.11]) by mx.google.com with ESMTPS id z135si52671290lfd.128.2019.01.07.05.03.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Jan 2019 05:03:02 -0800 (PST) Received-SPF: pass (google.com: domain of vincent.whitchurch@axis.com designates 195.60.68.11 as permitted sender) client-ip=195.60.68.11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of vincent.whitchurch@axis.com designates 195.60.68.11 as permitted sender) smtp.mailfrom=vincent.whitchurch@axis.com Received: from localhost (localhost [127.0.0.1]) by bastet.se.axis.com (Postfix) with ESMTP id 8F9B21844B; Mon, 7 Jan 2019 14:03:01 +0100 (CET) X-Axis-User: NO X-Axis-NonUser: YES X-Virus-Scanned: Debian amavisd-new at bastet.se.axis.com Received: from bastet.se.axis.com ([IPv6:::ffff:127.0.0.1]) by localhost (bastet.se.axis.com [::ffff:127.0.0.1]) (amavisd-new, port 10024) with LMTP id RbzXBgy2OCTx; Mon, 7 Jan 2019 14:03:00 +0100 (CET) Received: from boulder02.se.axis.com (boulder02.se.axis.com [10.0.8.16]) by bastet.se.axis.com (Postfix) with ESMTPS id 2C43C18351; Mon, 7 Jan 2019 14:03:00 +0100 (CET) Received: from boulder02.se.axis.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 145381A065; Mon, 7 Jan 2019 14:03:00 +0100 (CET) Received: from boulder02.se.axis.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 07D8E1A064; Mon, 7 Jan 2019 14:03:00 +0100 (CET) Received: from thoth.se.axis.com (unknown [10.0.2.173]) by boulder02.se.axis.com (Postfix) with ESMTP; Mon, 7 Jan 2019 14:02:59 +0100 (CET) Received: from lnxartpec.se.axis.com (lnxartpec.se.axis.com [10.88.4.9]) by thoth.se.axis.com (Postfix) with ESMTP id EF72B1C75; Mon, 7 Jan 2019 14:02:59 +0100 (CET) Received: by lnxartpec.se.axis.com (Postfix, from userid 10564) id EB0458017A; Mon, 7 Jan 2019 14:02:59 +0100 (CET) From: Vincent Whitchurch To: akpm@linux-foundation.org Cc: viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, mcgrof@kernel.org, keescook@chromium.org, corbet@lwn.net, linux-doc@vger.kernel.org, Vincent Whitchurch Subject: [PATCH] drop_caches: Allow unmapping pages Date: Mon, 7 Jan 2019 14:02:39 +0100 Message-Id: <20190107130239.3417-1-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.20.0 MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP drop_caches does not drop pages which are currently mapped. Add an option to try to unmap and drop even these pages. This provides a simple way to obtain a rough estimate of how many file pages are used in a particular use case: drop everything and check how much gets read back. # cat /proc/meminfo | grep file Active(file): 16608 kB Inactive(file): 23424 kB # echo 3 > /proc/sys/vm/drop_caches && cat /proc/meminfo | grep file Active(file): 10624 kB Inactive(file): 15060 kB # echo 11 > /proc/sys/vm/drop_caches && cat /proc/meminfo | grep file Active(file): 240 kB Inactive(file): 2344 kB Signed-off-by: Vincent Whitchurch --- Documentation/sysctl/vm.txt | 4 ++++ fs/drop_caches.c | 3 ++- include/linux/fs.h | 10 ++++++++-- kernel/sysctl.c | 4 ++-- mm/truncate.c | 39 ++++++++++++++++++++++++------------- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 187ce4f599a2..6ea06c2c973b 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -222,6 +222,10 @@ To increase the number of objects freed by this operation, the user may run number of dirty objects on the system and create more candidates to be dropped. +By default, pages which are currently mapped are not dropped from the +pagecache. If you want to unmap and drop these pages too, echo 9 or 11 instead +of 1 or 3 respectively (set bit 4). + This file is not a means to control the growth of the various kernel caches (inodes, dentries, pagecache, etc...) These objects are automatically reclaimed by the kernel when memory is needed elsewhere on the system. diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 82377017130f..9faaa1e3a672 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -17,6 +17,7 @@ int sysctl_drop_caches; static void drop_pagecache_sb(struct super_block *sb, void *unused) { struct inode *inode, *toput_inode = NULL; + bool unmap = sysctl_drop_caches & 8; spin_lock(&sb->s_inode_list_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { @@ -30,7 +31,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) spin_unlock(&inode->i_lock); spin_unlock(&sb->s_inode_list_lock); - invalidate_mapping_pages(inode->i_mapping, 0, -1); + __invalidate_mapping_pages(inode->i_mapping, 0, -1, unmap); iput(toput_inode); toput_inode = inode; diff --git a/include/linux/fs.h b/include/linux/fs.h index 811c77743dad..503e176654ce 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2675,8 +2675,14 @@ extern int check_disk_change(struct block_device *); extern int __invalidate_device(struct block_device *, bool); extern int invalidate_partition(struct gendisk *, int); #endif -unsigned long invalidate_mapping_pages(struct address_space *mapping, - pgoff_t start, pgoff_t end); +unsigned long __invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end, bool unmap); + +static inline unsigned long invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end) +{ + return __invalidate_mapping_pages(mapping, start, end, false); +} static inline void invalidate_remote_inode(struct inode *inode) { diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ba4d9e85feb8..f12c2a8d84fb 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -125,7 +125,7 @@ static int __maybe_unused neg_one = -1; static int zero; static int __maybe_unused one = 1; static int __maybe_unused two = 2; -static int __maybe_unused four = 4; +static int __maybe_unused fifteen = 15; static unsigned long one_ul = 1; static int one_hundred = 100; static int one_thousand = 1000; @@ -1431,7 +1431,7 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = drop_caches_sysctl_handler, .extra1 = &one, - .extra2 = &four, + .extra2 = &fifteen, }, #ifdef CONFIG_COMPACTION { diff --git a/mm/truncate.c b/mm/truncate.c index 798e7ccfb030..613b02e02146 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -245,6 +245,22 @@ int generic_error_remove_page(struct address_space *mapping, struct page *page) } EXPORT_SYMBOL(generic_error_remove_page); +static int __invalidate_inode_page(struct page *page, bool unmap) +{ + struct address_space *mapping = page_mapping(page); + if (!mapping) + return 0; + if (PageDirty(page) || PageWriteback(page)) + return 0; + if (page_mapped(page)) { + if (!unmap) + return 0; + if (!try_to_unmap(page, TTU_IGNORE_ACCESS)) + return 0; + } + return invalidate_complete_page(mapping, page); +} + /* * Safely invalidate one page from its pagecache mapping. * It only drops clean, unused pages. The page must be locked. @@ -253,16 +269,10 @@ EXPORT_SYMBOL(generic_error_remove_page); */ int invalidate_inode_page(struct page *page) { - struct address_space *mapping = page_mapping(page); - if (!mapping) - return 0; - if (PageDirty(page) || PageWriteback(page)) - return 0; - if (page_mapped(page)) - return 0; - return invalidate_complete_page(mapping, page); + return __invalidate_inode_page(page, false); } + /** * truncate_inode_pages_range - truncate range of pages specified by start & end byte offsets * @mapping: mapping to truncate @@ -532,16 +542,17 @@ EXPORT_SYMBOL(truncate_inode_pages_final); * @mapping: the address_space which holds the pages to invalidate * @start: the offset 'from' which to invalidate * @end: the offset 'to' which to invalidate (inclusive) + * @unmap: try to unmap pages * * This function only removes the unlocked pages, if you want to * remove all the pages of one inode, you must call truncate_inode_pages. * * invalidate_mapping_pages() will not block on IO activity. It will not - * invalidate pages which are dirty, locked, under writeback or mapped into - * pagetables. + * invalidate pages which are dirty, locked, under writeback or, if unmap is + * false, mapped into pagetables. */ -unsigned long invalidate_mapping_pages(struct address_space *mapping, - pgoff_t start, pgoff_t end) +unsigned long __invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end, bool unmap) { pgoff_t indices[PAGEVEC_SIZE]; struct pagevec pvec; @@ -591,7 +602,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, } } - ret = invalidate_inode_page(page); + ret = __invalidate_inode_page(page, unmap); unlock_page(page); /* * Invalidation is a hint that the page is no longer @@ -608,7 +619,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, } return count; } -EXPORT_SYMBOL(invalidate_mapping_pages); +EXPORT_SYMBOL(__invalidate_mapping_pages); /* * This is like invalidate_complete_page(), except it ignores the page's