From patchwork Fri Aug 30 12:43:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinayak Menon X-Patchwork-Id: 11123875 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 11E3014DE for ; Fri, 30 Aug 2019 12:44:07 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id CF3CC2186A for ; Fri, 30 Aug 2019 12:44:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="WcGMRhKH"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="WcGMRhKH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CF3CC2186A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 10C5F6B0008; Fri, 30 Aug 2019 08:44:06 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 0BE5C6B000A; Fri, 30 Aug 2019 08:44:06 -0400 (EDT) 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 EED606B000C; Fri, 30 Aug 2019 08:44:05 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0152.hostedemail.com [216.40.44.152]) by kanga.kvack.org (Postfix) with ESMTP id C84E16B0008 for ; Fri, 30 Aug 2019 08:44:05 -0400 (EDT) Received: from smtpin08.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 7AD371F85A for ; Fri, 30 Aug 2019 12:44:05 +0000 (UTC) X-FDA: 75879061650.08.song60_68e387b2693e X-Spam-Summary: 2,0,0,3419c2d1d642c703,d41d8cd98f00b204,vinmenon@codeaurora.org,:minchan@kernel.org::vinmenon@codeaurora.org,RULES_HIT:41:355:379:541:800:960:966:973:988:989:1260:1345:1437:1535:1543:1711:1730:1747:1777:1792:1801:2196:2198:2199:2200:2393:2540:2559:2562:2693:2731:3138:3139:3140:3141:3142:3355:3865:3866:3867:3868:3870:3871:3874:4250:4385:4605:5007:6261:6653:7903:7974:9121:9592:10004:11026:11218:11232:11233:11473:11658:11914:12043:12295:12296:12297:12438:12517:12519:12555:13161:13229:14096:14181:14394:14721:14877:21080:21324:21325:21451:21627:21795:30003:30012:30051:30054:30070,0,RBL:198.145.29.96:@codeaurora.org:.lbl8.mailshell.net-62.14.0.100 64.201.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:26,LUA_SUMMARY:none X-HE-Tag: song60_68e387b2693e X-Filterd-Recvd-Size: 5543 Received: from smtp.codeaurora.org (smtp.codeaurora.org [198.145.29.96]) by imf39.hostedemail.com (Postfix) with ESMTP for ; Fri, 30 Aug 2019 12:44:04 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1000) id D7D90602F2; Fri, 30 Aug 2019 12:44:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1567169043; bh=bTajOsLB1qZ5mlLoBtttO/RiZmPYso1abxbVOc2sF1k=; h=From:To:Cc:Subject:Date:From; b=WcGMRhKH7dqg/RNz2k9+tZ6Lkx/TEVGnSUEFrN8eFB7irkhE18hV2LRPTDJKgM7Qn MN0tcPgRaF7kKK6owPJZt1vkR9aej15j0KkIzQw1+ml5seMSQMgeDf9+CYIuKjDOpc Rco8K/GuKAREebJKMqPOd9OzMfpyTcBFtQYzY0p0= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_INVALID,DKIM_SIGNED,SPF_NONE autolearn=no autolearn_force=no version=3.4.0 Received: from vinmenon-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vinmenon@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id E7D5E602F2; Fri, 30 Aug 2019 12:44:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1567169043; bh=bTajOsLB1qZ5mlLoBtttO/RiZmPYso1abxbVOc2sF1k=; h=From:To:Cc:Subject:Date:From; b=WcGMRhKH7dqg/RNz2k9+tZ6Lkx/TEVGnSUEFrN8eFB7irkhE18hV2LRPTDJKgM7Qn MN0tcPgRaF7kKK6owPJZt1vkR9aej15j0KkIzQw1+ml5seMSQMgeDf9+CYIuKjDOpc Rco8K/GuKAREebJKMqPOd9OzMfpyTcBFtQYzY0p0= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E7D5E602F2 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=vinmenon@codeaurora.org From: Vinayak Menon To: minchan@kernel.org, linux-mm@kvack.org Cc: Vinayak Menon Subject: [PATCH] mm: fix the race between swapin_readahead and SWP_SYNCHRONOUS_IO path Date: Fri, 30 Aug 2019 18:13:31 +0530 Message-Id: <1567169011-4748-1-git-send-email-vinmenon@codeaurora.org> X-Mailer: git-send-email 2.7.4 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: The following race is observed due to which a processes faulting on a swap entry, finds the page neither in swapcache nor swap. This causes zram to give a zero filled page that gets mapped to the process, resulting in a user space crash later. Consider parent and child processes Pa and Pb sharing the same swap slot with swap_count 2. Swap is on zram with SWP_SYNCHRONOUS_IO set. Virtual address 'VA' of Pa and Pb points to the shared swap entry. Pa Pb fault on VA fault on VA do_swap_page do_swap_page lookup_swap_cache fails lookup_swap_cache fails Pb scheduled out swapin_readahead (deletes zram entry) swap_free (makes swap_count 1) Pb scheduled in swap_readpage (swap_count == 1) Takes SWP_SYNCHRONOUS_IO path zram enrty absent zram gives a zero filled page Fix this by reading the swap_count before lookup_swap_cache, which conforms with the order in which page is added to swap cache and swap count is decremented in do_swap_page. In the race case above, this will let Pb take the readahead path and thus pick the proper page from swapcache. Signed-off-by: Vinayak Menon --- mm/memory.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index e0c232f..22643aa 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2744,6 +2744,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) struct page *page = NULL, *swapcache; struct mem_cgroup *memcg; swp_entry_t entry; + struct swap_info_struct *si; + bool skip_swapcache = false; pte_t pte; int locked; int exclusive = 0; @@ -2771,15 +2773,24 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) delayacct_set_flag(DELAYACCT_PF_SWAPIN); + + /* + * lookup_swap_cache below can fail and before the SWP_SYNCHRONOUS_IO + * check is made, another process can populate the swapcache, delete + * the swap entry and decrement the swap count. So decide on taking + * the SWP_SYNCHRONOUS_IO path before the lookup. In the event of the + * race described, the victim process will find a swap_count > 1 + * and can then take the readahead path instead of SWP_SYNCHRONOUS_IO. + */ + si = swp_swap_info(entry); + if (si->flags & SWP_SYNCHRONOUS_IO && __swap_count(entry) == 1) + skip_swapcache = true; + page = lookup_swap_cache(entry, vma, vmf->address); swapcache = page; if (!page) { - struct swap_info_struct *si = swp_swap_info(entry); - - if (si->flags & SWP_SYNCHRONOUS_IO && - __swap_count(entry) == 1) { - /* skip swapcache */ + if (skip_swapcache) { page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address); if (page) {