From patchwork Mon Sep 24 02:20:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 973815 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42JScG2JLTz9sBZ; Mon, 24 Sep 2018 12:21:02 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1g4GUa-0001Xb-9D; Mon, 24 Sep 2018 02:20:56 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1g4GUX-0001XA-TJ for kernel-team@lists.canonical.com; Mon, 24 Sep 2018 02:20:53 +0000 Received: from mail-pl1-f198.google.com ([209.85.214.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1g4GUX-00084b-H0 for kernel-team@lists.canonical.com; Mon, 24 Sep 2018 02:20:53 +0000 Received: by mail-pl1-f198.google.com with SMTP id w18-v6so9406076plp.3 for ; Sun, 23 Sep 2018 19:20:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BREESgfAwoVTCN3RSlqb6kFCCCtXFAllC41NdzBn/cw=; b=qz9KzAsMbAggJOhOsZfVu9/azrXCE5TxlG+KwZfGo9kjknx7ptORiqfCMGH/ZCiYAp EdyoRrFWb0WlKTdA82T1OcYLSHnDE2WQARWTS7dhFzfcxTFtC2YmsFdomAroUL1sRV8/ xQ379Kwm+bwTn2EAxQr9F4WiJFWGQveXKbDqi6pwzQDChqqYqCbPu27D2BZIdR1wTFyY kYGofzrE2xxlfbqNEuTHkKDAq0Xp7pt93hXgRDY4ybW5KIqi89wIVXSi8/L/FlQH7x9U MzGBe7EPZEk/QGu2dPy483T9vkysxF4p2r/tTfkp0rdC4zW7tMc3xbbXu6NfwOe4askG 2lgQ== X-Gm-Message-State: ABuFfogck2EWDuUsh1ZuiYa1fdh0UIy06ZvYXu2sGDusYcf0ml4K4Eu3 nbdRPtR3xYhXz+y4zkzeA6qQCCD+friGKs7K2JhZklG6L+muoyf19aXvQ1kHlmg6dm3BuZ3AK6p ejqTR1zSP3mSfc9Uj/nPF7uNsvzB+wPXIWGxBhNAiNlrhIBI9 X-Received: by 2002:a17:902:b7c3:: with SMTP id v3-v6mr7287724plz.182.1537755652119; Sun, 23 Sep 2018 19:20:52 -0700 (PDT) X-Google-Smtp-Source: ACcGV60SWOvjUYbIPyyV7aMTiGgMBDhHjnU0n6xkUSMwlaCxvqqCuihI5tB7y926VQ0wGhSNJ/0EBA== X-Received: by 2002:a17:902:b7c3:: with SMTP id v3-v6mr7287713plz.182.1537755651883; Sun, 23 Sep 2018 19:20:51 -0700 (PDT) Received: from linkitivity.iinet.net.au (dip-220-235-51-100.wa.westnet.com.au. [220.235.51.100]) by smtp.gmail.com with ESMTPSA id u9-v6sm46672101pfi.104.2018.09.23.19.20.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Sep 2018 19:20:51 -0700 (PDT) From: Daniel Axtens To: kernel-team@lists.canonical.com Subject: [SRU X][PATCH v2 1/1] UBUNTU: SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan is active Date: Mon, 24 Sep 2018 12:20:44 +1000 Message-Id: <20180924022044.1678-2-daniel.axtens@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180924022044.1678-1-daniel.axtens@canonical.com> References: <20180924022044.1678-1-daniel.axtens@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kiran.modukuri@gmail.com MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Kiran Kumar Modukuri BugLink: https://bugs.launchpad.net/bugs/1793430 [Description] In a heavily loaded system where the system pagecache is nearing memory limits and fscache is enabled, pages can be leaked by fscache while trying read pages from cachefiles backend. This can happen because two applications can be reading same page from a single mount, two threads can be trying to read the backing page at same time. This results in one of the thread finding that a page for the backing file or netfs file is already in the radix tree. During the error handling cachefiles does not cleanup the reference on backing page, leading to page leak. [Fix] The fix is straightforward, to decrement the reference when error is encounterd. [Testing] I have tested the fix using following method for 12+ hrs. 1) mkdir -p /mnt/nfs ; mount -o vers=3,fsc :/export /mnt/nfs 2) create 10000 files of 2.8MB in a NFS mount. 3) start a thread to simulate heavy VM presssure (while true ; do echo 3 > /proc/sys/vm/drop_caches ; sleep 1 ; done)& 4) start multiple parallel reader for data set at same time find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & .. .. find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & find /mnt/nfs -type f | xargs -P 80 cat > /dev/null & 5) finally check using cat /proc/fs/fscache/stats | grep -i pages ; free -h , cat /proc/meminfo and page-types -r -b lru to ensure all pages are freed. Reviewed-by: Daniel Axtens Signed-off-by: Shantanu Goel Signed-off-by: Kiran Kumar Modukuri [dja: forward ported to current upstream] Signed-off-by: Daniel Axtens [backported from https://www.redhat.com/archives/linux-cachefs/2018-September/msg00002.html This is v3 of the patch. v2 has sat on the list for weeks without any response or forward progress. v1 was first posted in 2014 and was reposted this August.] Signed-off-by: Daniel Axtens Acked-by: Stefan Bader --- Canonical v2/Upstream v3: Clean up per Seth's feedback. --- fs/cachefiles/rdwr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 5b68cf526887..98e2b89dc47e 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -513,6 +513,8 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, goto installed_new_backing_page; if (ret != -EEXIST) goto nomem; + page_cache_release(newpage); + newpage = NULL; } /* we've installed a new backing page, so now we need @@ -537,7 +539,10 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, netpage->index, cachefiles_gfp); if (ret < 0) { if (ret == -EEXIST) { + page_cache_release(backpage); + backpage = NULL; page_cache_release(netpage); + netpage = NULL; fscache_retrieval_complete(op, 1); continue; } @@ -610,7 +615,10 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object, netpage->index, cachefiles_gfp); if (ret < 0) { if (ret == -EEXIST) { + page_cache_release(backpage); + backpage = NULL; page_cache_release(netpage); + netpage = NULL; fscache_retrieval_complete(op, 1); continue; }