All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miaohe Lin <linmiaohe@huawei.com>
To: <akpm@linux-foundation.org>
Cc: <ying.huang@intel.com>, <dennis@kernel.org>,
	<tim.c.chen@linux.intel.com>, <hughd@google.com>,
	<hannes@cmpxchg.org>, <mhocko@suse.com>, <iamjoonsoo.kim@lge.com>,
	<alexs@kernel.org>, <willy@infradead.org>, <minchan@kernel.org>,
	<richard.weiyang@gmail.com>, <shy828301@gmail.com>,
	<david@redhat.com>, <linux-kernel@vger.kernel.org>,
	<linux-mm@kvack.org>, <linmiaohe@huawei.com>
Subject: [PATCH v4 4/4] mm/shmem: fix shmem_swapin() race with swapoff
Date: Sun, 25 Apr 2021 10:38:06 +0800	[thread overview]
Message-ID: <20210425023806.3537283-5-linmiaohe@huawei.com> (raw)
In-Reply-To: <20210425023806.3537283-1-linmiaohe@huawei.com>

When I was investigating the swap code, I found the below possible race
window:

CPU 1                                         CPU 2
-----                                         -----
shmem_swapin
  swap_cluster_readahead
    if (likely(si->flags & (SWP_BLKDEV | SWP_FS_OPS))) {
                                              swapoff
                                                ..
                                                si->swap_file = NULL;
                                                ..
    struct inode *inode = si->swap_file->f_mapping->host;[oops!]

Close this race window by using get/put_swap_device() to guard against
concurrent swapoff.

Fixes: 8fd2e0b505d1 ("mm: swap: check if swap backing device is congested or not")
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
---
 mm/shmem.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/mm/shmem.c b/mm/shmem.c
index 26c76b13ad23..be388d0cf8b5 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1696,6 +1696,7 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
 	struct address_space *mapping = inode->i_mapping;
 	struct shmem_inode_info *info = SHMEM_I(inode);
 	struct mm_struct *charge_mm = vma ? vma->vm_mm : current->mm;
+	struct swap_info_struct *si;
 	struct page *page;
 	swp_entry_t swap;
 	int error;
@@ -1704,6 +1705,12 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
 	swap = radix_to_swp_entry(*pagep);
 	*pagep = NULL;
 
+	/* Prevent swapoff from happening to us. */
+	si = get_swap_device(swap);
+	if (unlikely(!si)) {
+		error = EINVAL;
+		goto failed;
+	}
 	/* Look it up and read it in.. */
 	page = lookup_swap_cache(swap, NULL, 0);
 	if (!page) {
@@ -1720,6 +1727,7 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
 			goto failed;
 		}
 	}
+	put_swap_device(si);
 
 	/* We have to do this with page locked to prevent races */
 	lock_page(page);
@@ -1775,6 +1783,9 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
 		put_page(page);
 	}
 
+	if (si)
+		put_swap_device(si);
+
 	return error;
 }
 
-- 
2.19.1


  parent reply	other threads:[~2021-04-25  2:38 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-25  2:38 [PATCH v4 0/4] close various race windows for swap Miaohe Lin
2021-04-25  2:38 ` [PATCH v4 1/4] mm/swapfile: use percpu_ref to serialize against concurrent swapoff Miaohe Lin
2021-04-25  2:38 ` [PATCH v4 2/4] swap: fix do_swap_page() race with swapoff Miaohe Lin
2021-04-25  3:08   ` Huang, Ying
2021-04-25  3:08     ` Huang, Ying
2021-04-25  2:38 ` [PATCH v4 3/4] mm/swap: remove confusing checking for non_swap_entry() in swap_ra_info() Miaohe Lin
2021-04-25  3:09   ` Huang, Ying
2021-04-25  3:09     ` Huang, Ying
2021-04-25  2:38 ` Miaohe Lin [this message]
2021-04-25  3:07   ` [PATCH v4 4/4] mm/shmem: fix shmem_swapin() race with swapoff Huang, Ying
2021-04-25  3:07     ` Huang, Ying
2021-04-25  3:33     ` Miaohe Lin
2021-04-25  4:20       ` Huang, Ying
2021-04-25  4:20         ` Huang, Ying
2021-04-25  6:27         ` Miaohe Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210425023806.3537283-5-linmiaohe@huawei.com \
    --to=linmiaohe@huawei.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexs@kernel.org \
    --cc=david@redhat.com \
    --cc=dennis@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@suse.com \
    --cc=minchan@kernel.org \
    --cc=richard.weiyang@gmail.com \
    --cc=shy828301@gmail.com \
    --cc=tim.c.chen@linux.intel.com \
    --cc=willy@infradead.org \
    --cc=ying.huang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.