Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2828727pxv; Mon, 12 Jul 2021 02:58:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy/BqGX2uywJyF2LSsC8C+FkdDJjc/4Oj7epA7stNKRUlLhhw7Inm820MRLVoFl+KVsT3uT X-Received: by 2002:a05:6602:3404:: with SMTP id n4mr19735799ioz.19.1626083920013; Mon, 12 Jul 2021 02:58:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626083920; cv=none; d=google.com; s=arc-20160816; b=pRe/URKRXJLs4jNHg+jtAbV1tZ4pdhwP06y7sUNPPuBzCAIWFtzEiDlXY9EscK7CLu HwnbbksRjgHWn1Q4yUXif6G0GSGBQsNw3wx1k+uueufgolh9wx8aA3WO3TSe/nYRkD+8 RV3IrcKurMZukOJXRo5EADaaD18nszpILYh9BOojdlnCDeCBnCP+9f1Z3dm+5zIL8Vh2 lqZIsQx5LBC+zCSJTN/cxnrRA7pLgrAZ4XPnWEXCEQthdlKUnWxl9LxS48N7n4mgdUl2 qm/Moh5WmMkw3A7Kp4w3EYWDR5uE5aTQ0mYMgtXYhAKivPpQd1zpshJeeTYJXq/TG8vA m14A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=LrUhADphP3hVPQhktwDE4gCe09Wv96lnoy9F8p5Ub6M=; b=BjInHdWLcj6usoWryEIrhoRC3J+WjWSdEDUx719dGk6SWXRF9kGO+jNn76OkMATkS1 hYLWnGkkIENJ0j/qdjNqu5rjyVm3zdwbrYG084HLX10TAF4lLucstEU1LNjxijeemDUp R44QG0cetjUlMcP9Ywb01peOlJINdxoukUw6IzbiPWHx42h0PQkl0sfZOtNQde2uO1KE lH+K0SeqcJvwDl7NJ3Llz36UkQzpvTqr6vMOoc9OZi08BmyPJppdh4A39E/2jlvN6tUQ M8uksbZQ8ay7zt05hq+7VujJbWrwIBpFgDLI9EAY1MdONIXrKXQIemICaVT7zbhFvYFU I/jQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="Hj4N/EOV"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r9si16857446jad.24.2021.07.12.02.58.28; Mon, 12 Jul 2021 02:58:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="Hj4N/EOV"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241953AbhGLHAs (ORCPT + 99 others); Mon, 12 Jul 2021 03:00:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:37048 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239147AbhGLGot (ORCPT ); Mon, 12 Jul 2021 02:44:49 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id EBB8861166; Mon, 12 Jul 2021 06:40:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626072046; bh=Tjspu3mv9SqLExVfSLZzUuxAF1pscHT6bLPzziyAcjI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Hj4N/EOVYdRrFRRp0SkERyqKiLndQI4epsFxeHoOfxOH2SkJ7IDUUqZMdPMVxHGP1 dCUSIbS8bLMffta+6IgZu0TY0UwcmEffoGsCWRiwnRS2pcPqv5BsSvnERfEGVcbSRP tpq75uPHcACHM8Zdt0LQdK4wc6iYez83eLUw3ScE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Miaohe Lin , "Huang, Ying" , Alex Shi , David Hildenbrand , Dennis Zhou , Hugh Dickins , Johannes Weiner , Joonsoo Kim , Matthew Wilcox , Michal Hocko , Minchan Kim , Tim Chen , Wei Yang , Yang Shi , Yu Zhao , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH 5.10 294/593] swap: fix do_swap_page() race with swapoff Date: Mon, 12 Jul 2021 08:07:34 +0200 Message-Id: <20210712060916.859590415@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060843.180606720@linuxfoundation.org> References: <20210712060843.180606720@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Miaohe Lin [ Upstream commit 2799e77529c2a25492a4395db93996e3dacd762d ] When I was investigating the swap code, I found the below possible race window: CPU 1 CPU 2 ----- ----- do_swap_page if (data_race(si->flags & SWP_SYNCHRONOUS_IO) swap_readpage if (data_race(sis->flags & SWP_FS_OPS)) { swapoff .. p->swap_file = NULL; .. struct file *swap_file = sis->swap_file; struct address_space *mapping = swap_file->f_mapping;[oops!] Note that for the pages that are swapped in through swap cache, this isn't an issue. Because the page is locked, and the swap entry will be marked with SWAP_HAS_CACHE, so swapoff() can not proceed until the page has been unlocked. Fix this race by using get/put_swap_device() to guard against concurrent swapoff. Link: https://lkml.kernel.org/r/20210426123316.806267-3-linmiaohe@huawei.com Fixes: 0bcac06f27d7 ("mm,swap: skip swapcache for swapin of synchronous device") Signed-off-by: Miaohe Lin Reviewed-by: "Huang, Ying" Cc: Alex Shi Cc: David Hildenbrand Cc: Dennis Zhou Cc: Hugh Dickins Cc: Johannes Weiner Cc: Joonsoo Kim Cc: Matthew Wilcox Cc: Michal Hocko Cc: Minchan Kim Cc: Tim Chen Cc: Wei Yang Cc: Yang Shi Cc: Yu Zhao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- include/linux/swap.h | 9 +++++++++ mm/memory.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index fbc6805358da..dfabf4660a67 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -503,6 +503,15 @@ static inline struct swap_info_struct *swp_swap_info(swp_entry_t entry) return NULL; } +static inline struct swap_info_struct *get_swap_device(swp_entry_t entry) +{ + return NULL; +} + +static inline void put_swap_device(struct swap_info_struct *si) +{ +} + #define swap_address_space(entry) (NULL) #define get_nr_swap_pages() 0L #define total_swap_pages 0L diff --git a/mm/memory.c b/mm/memory.c index eb31b3e4ef93..0a905e0a7e67 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3302,6 +3302,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct page *page = NULL, *swapcache; + struct swap_info_struct *si = NULL; swp_entry_t entry; pte_t pte; int locked; @@ -3329,14 +3330,16 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) goto out; } + /* Prevent swapoff from happening to us. */ + si = get_swap_device(entry); + if (unlikely(!si)) + goto out; delayacct_set_flag(DELAYACCT_PF_SWAPIN); page = lookup_swap_cache(entry, vma, vmf->address); swapcache = page; if (!page) { - struct swap_info_struct *si = swp_swap_info(entry); - if (data_race(si->flags & SWP_SYNCHRONOUS_IO) && __swap_count(entry) == 1) { /* skip swapcache */ @@ -3507,6 +3510,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) unlock: pte_unmap_unlock(vmf->pte, vmf->ptl); out: + if (si) + put_swap_device(si); return ret; out_nomap: pte_unmap_unlock(vmf->pte, vmf->ptl); @@ -3518,6 +3523,8 @@ out_release: unlock_page(swapcache); put_page(swapcache); } + if (si) + put_swap_device(si); return ret; } -- 2.30.2