From: Miaohe Lin <linmiaohe@huawei.com>
To: "Huang, Ying" <ying.huang@intel.com>
Cc: <akpm@linux-foundation.org>, <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>
Subject: Re: [PATCH v4 4/4] mm/shmem: fix shmem_swapin() race with swapoff
Date: Sun, 25 Apr 2021 11:33:42 +0800 [thread overview]
Message-ID: <0213893e-2b05-8d2e-9a79-e8a71db23644@huawei.com> (raw)
In-Reply-To: <87bla3xdt0.fsf@yhuang6-desk1.ccr.corp.intel.com>
On 2021/4/25 11:07, Huang, Ying wrote:
> Miaohe Lin <linmiaohe@huawei.com> writes:
>
>> 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);
>
> I think it's better to put_swap_device() just before returning from the
> function. It's not a big issue to slow down swapoff() a little. And
> this will make the logic easier to be understood.
>
shmem_swapin_page() already has a methed, i.e. locked page, to prevent races. I was intended
to not mix with that. But your suggestion is good as this will make the logic easier to be
understood.
Just to make sure, is this what you mean? Many thanks!
diff --git a/mm/shmem.c b/mm/shmem.c
index 26c76b13ad23..737e5b3200c3 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) {
@@ -1765,6 +1772,8 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
swap_free(swap);
*pagep = page;
+ if (si)
+ put_swap_device(si);
return 0;
failed:
if (!shmem_confirm_swap(mapping, index, swap))
@@ -1775,6 +1784,9 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
put_page(page);
}
+ if (si)
+ put_swap_device(si);
+
return error;
}
> Best Regards,
> Huang, Ying
>
>>
>> /* 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;
>> }
> .
>
next prev parent reply other threads:[~2021-04-25 3:33 UTC|newest]
Thread overview: 11+ 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 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 2:38 ` [PATCH v4 4/4] mm/shmem: fix shmem_swapin() race with swapoff Miaohe Lin
2021-04-25 3:07 ` Huang, Ying
2021-04-25 3:33 ` Miaohe Lin [this message]
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=0213893e-2b05-8d2e-9a79-e8a71db23644@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox