diff mbox series

[3/5] mm/swap_state: fix get_shadow_from_swap_cache() race with swapoff

Message ID 20210408130820.48233-4-linmiaohe@huawei.com (mailing list archive)
State New, archived
Headers show
Series close various race windows for swap | expand

Commit Message

Miaohe Lin April 8, 2021, 1:08 p.m. UTC
The function get_shadow_from_swap_cache() can race with swapoff, though
it's only called by do_swap_page() now.

Fixes: aae466b0052e ("mm/swap: implement workingset detection for anonymous LRU")
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
---
 mm/swap_state.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Huang, Ying April 13, 2021, 1:33 a.m. UTC | #1
Miaohe Lin <linmiaohe@huawei.com> writes:

> The function get_shadow_from_swap_cache() can race with swapoff, though
> it's only called by do_swap_page() now.
>
> Fixes: aae466b0052e ("mm/swap: implement workingset detection for anonymous LRU")
> Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>

This is unnecessary.  The only caller has guaranteed the swap device
from swapoff.

Best Regards,
Huang, Ying

> ---
>  mm/swap_state.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/mm/swap_state.c b/mm/swap_state.c
> index 272ea2108c9d..709c260d644a 100644
> --- a/mm/swap_state.c
> +++ b/mm/swap_state.c
> @@ -83,11 +83,14 @@ void show_swap_cache_info(void)
>  
>  void *get_shadow_from_swap_cache(swp_entry_t entry)
>  {
> -	struct address_space *address_space = swap_address_space(entry);
> -	pgoff_t idx = swp_offset(entry);
> +	struct swap_info_struct *si;
>  	struct page *page;
>  
> -	page = xa_load(&address_space->i_pages, idx);
> +	si = get_swap_device(entry);
> +	if (!si)
> +		return NULL;
> +	page = xa_load(&swap_address_space(entry)->i_pages, swp_offset(entry));
> +	put_swap_device(si);
>  	if (xa_is_value(page))
>  		return page;
>  	return NULL;
Miaohe Lin April 14, 2021, 2:42 a.m. UTC | #2
On 2021/4/13 9:33, Huang, Ying wrote:
> Miaohe Lin <linmiaohe@huawei.com> writes:
> 
>> The function get_shadow_from_swap_cache() can race with swapoff, though
>> it's only called by do_swap_page() now.
>>
>> Fixes: aae466b0052e ("mm/swap: implement workingset detection for anonymous LRU")
>> Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
> 
> This is unnecessary.  The only caller has guaranteed the swap device
> from swapoff

Ok. This patch is just in case get_shadow_from_swap_cache() would be
called from elsewhere someday.

It's unnecessary and can be dropped now

.
> 
> Best Regards,
> Huang, Ying
> 
>> ---
>>  mm/swap_state.c | 9 ++++++---
>>  1 file changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/mm/swap_state.c b/mm/swap_state.c
>> index 272ea2108c9d..709c260d644a 100644
>> --- a/mm/swap_state.c
>> +++ b/mm/swap_state.c
>> @@ -83,11 +83,14 @@ void show_swap_cache_info(void)
>>  
>>  void *get_shadow_from_swap_cache(swp_entry_t entry)
>>  {
>> -	struct address_space *address_space = swap_address_space(entry);
>> -	pgoff_t idx = swp_offset(entry);
>> +	struct swap_info_struct *si;
>>  	struct page *page;
>>  
>> -	page = xa_load(&address_space->i_pages, idx);
>> +	si = get_swap_device(entry);
>> +	if (!si)
>> +		return NULL;
>> +	page = xa_load(&swap_address_space(entry)->i_pages, swp_offset(entry));
>> +	put_swap_device(si);
>>  	if (xa_is_value(page))
>>  		return page;
>>  	return NULL;
> 
> .
>
diff mbox series

Patch

diff --git a/mm/swap_state.c b/mm/swap_state.c
index 272ea2108c9d..709c260d644a 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -83,11 +83,14 @@  void show_swap_cache_info(void)
 
 void *get_shadow_from_swap_cache(swp_entry_t entry)
 {
-	struct address_space *address_space = swap_address_space(entry);
-	pgoff_t idx = swp_offset(entry);
+	struct swap_info_struct *si;
 	struct page *page;
 
-	page = xa_load(&address_space->i_pages, idx);
+	si = get_swap_device(entry);
+	if (!si)
+		return NULL;
+	page = xa_load(&swap_address_space(entry)->i_pages, swp_offset(entry));
+	put_swap_device(si);
 	if (xa_is_value(page))
 		return page;
 	return NULL;