Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2848898pxv; Mon, 12 Jul 2021 03:29:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwVR+2lOC5VDJkI6+8W5kiNR4W7kc/FHdPpxVkm2zzvwFYRjka4ikSki+E9qxPXj9eNKsQG X-Received: by 2002:a92:c0ca:: with SMTP id t10mr39572677ilf.241.1626085757098; Mon, 12 Jul 2021 03:29:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626085757; cv=none; d=google.com; s=arc-20160816; b=CCIvaScWZmU0Y57wsKHx57SpHw9lzFwHS7UQ+MuTnqdURwiZ8MmXjjDDzL6By6fP6F lRW1K5YFoQ5ZKOTsNvUPVwcdUjPqAuOQMt3LRluvNoRrzpFxdfw6eNwxK89ORRkITnu7 doHJlqjbduAlmyiplJqWWnQvNf4BdMECa1KfMjo9a4nOsAcxyAodq50vqsC8wPgkSKAL wIts1dEekCselTjSdOKTHVnqFSUeSOxoLnoIpsRrLhHtbeeFiEFEqTYbV2ciAlW2/l4t OcFKf6A90Wpqhz7nDhexOkrsCicNuCA6FeVePakmwhOgh8Cyc+bp3J9FSw4WhseVdwwj ZPHA== 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=Z3Sy9FB6H9fG75s19/SgvQTS5yWEjXpOqojRIWQGZ+w=; b=u9b6flYT5Hc9vUbMClwfYNSeLD1BddBOjHj1Ka3wuOXn19mCfPqhkysnFANU0qavF8 tpv9M8WbcYdoaPauxXJbaeI4vploNZdRjuG/dFjn985GPB9wcYEpM8sG4v+aDb52zx+f QI72uSyyoVUWb/67LWzA0l4LLGjj00LgFXCRuF79vebN0KBgnra63jdKBMpK3cu2SeM7 3DZKevNM9HH4BYHenxmJ3Q3Hrrn4mliwj6W/vmGLM4ryk/9lBZnm/0BUU/jZhhvz/QYz 6JU1KZrXZebnViW+SeOjzRUQ0iF/t7Nzy45Z4LueScJNmR4FRhM0P5VacLeBSeEzZMMI S4cQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iHgOvk4J; 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 b3si14186617iln.124.2021.07.12.03.29.05; Mon, 12 Jul 2021 03:29:17 -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=iHgOvk4J; 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 S1349640AbhGLHoZ (ORCPT + 99 others); Mon, 12 Jul 2021 03:44:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:46652 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242714AbhGLHMJ (ORCPT ); Mon, 12 Jul 2021 03:12:09 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1B35061165; Mon, 12 Jul 2021 07:09:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626073756; bh=qnd+jw3V5VbD3ni4aS3mZ9Fa4YdcuPvBFm0G7czPa0c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iHgOvk4J8UPZBHWP7bi0jj9T7dL2ff8zak6eLOEg/OA+uxeTYFuoL8lfwN0I5eie1 SlH1duGrLR3DINqnx9xQOM30OvxMSZFKl32NevQYyTIrR387+uEoMYqfHwYGhatbFL at2QuJpOot35r9OtQMQ40fEtDTyran3pgdVzbN/w= 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.12 347/700] swap: fix do_swap_page() race with swapoff Date: Mon, 12 Jul 2021 08:07:10 +0200 Message-Id: <20210712061013.209674834@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060924.797321836@linuxfoundation.org> References: <20210712060924.797321836@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 4cc6ec3bf0ab..7482f8b968ea 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -504,6 +504,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 36624986130b..e0073089bc9f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3310,6 +3310,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; @@ -3337,14 +3338,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 */ @@ -3515,6 +3518,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); @@ -3526,6 +3531,8 @@ out_release: unlock_page(swapcache); put_page(swapcache); } + if (si) + put_swap_device(si); return ret; } -- 2.30.2