- * [PATCH rfc 1/9] mm: migrate: simplify __buffer_migrate_folio()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-02-01 19:12   ` Matthew Wilcox
  2024-01-29  7:09 ` [PATCH rfc 2/9] mm: migrate_device: use more folio in __migrate_device_pages() Kefeng Wang
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
Use filemap_migrate_folio() helper to simplify __buffer_migrate_folio().
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 mm/migrate.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index cc9f2bcd73b4..cdae25b7105f 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -774,24 +774,16 @@ static int __buffer_migrate_folio(struct address_space *mapping,
 		}
 	}
 
-	rc = folio_migrate_mapping(mapping, dst, src, 0);
+	rc = filemap_migrate_folio(mapping, dst, src, mode);
 	if (rc != MIGRATEPAGE_SUCCESS)
 		goto unlock_buffers;
 
-	folio_attach_private(dst, folio_detach_private(src));
-
 	bh = head;
 	do {
 		folio_set_bh(bh, dst, bh_offset(bh));
 		bh = bh->b_this_page;
 	} while (bh != head);
 
-	if (mode != MIGRATE_SYNC_NO_COPY)
-		folio_migrate_copy(dst, src);
-	else
-		folio_migrate_flags(dst, src);
-
-	rc = MIGRATEPAGE_SUCCESS;
 unlock_buffers:
 	if (check_refs)
 		spin_unlock(&mapping->i_private_lock);
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * Re: [PATCH rfc 1/9] mm: migrate: simplify __buffer_migrate_folio()
  2024-01-29  7:09 ` [PATCH rfc 1/9] mm: migrate: simplify __buffer_migrate_folio() Kefeng Wang
@ 2024-02-01 19:12   ` Matthew Wilcox
  0 siblings, 0 replies; 19+ messages in thread
From: Matthew Wilcox @ 2024-02-01 19:12 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On Mon, Jan 29, 2024 at 03:09:26PM +0800, Kefeng Wang wrote:
> @@ -774,24 +774,16 @@ static int __buffer_migrate_folio(struct address_space *mapping,
>  		}
>  	}
>  
> -	rc = folio_migrate_mapping(mapping, dst, src, 0);
> +	rc = filemap_migrate_folio(mapping, dst, src, mode);
>  	if (rc != MIGRATEPAGE_SUCCESS)
>  		goto unlock_buffers;
>  
> -	folio_attach_private(dst, folio_detach_private(src));
> -
>  	bh = head;
>  	do {
>  		folio_set_bh(bh, dst, bh_offset(bh));
>  		bh = bh->b_this_page;
>  	} while (bh != head);
>  
> -	if (mode != MIGRATE_SYNC_NO_COPY)
> -		folio_migrate_copy(dst, src);
> -	else
> -		folio_migrate_flags(dst, src);
> -
> -	rc = MIGRATEPAGE_SUCCESS;
I wondered if maybe there was an ordering requirement; that we had to
set up the BHs before copying the data over.  But I don't think there
is; the page should be frozen, the buffer heads are locked, and I don't
think the ordering matters.  So ...
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
^ permalink raw reply	[flat|nested] 19+ messages in thread
 
- * [PATCH rfc 2/9] mm: migrate_device: use more folio in __migrate_device_pages()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 1/9] mm: migrate: simplify __buffer_migrate_folio() Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-02-01 19:27   ` Matthew Wilcox
  2024-01-29  7:09 ` [PATCH rfc 3/9] mm: migrate: remove migrate_folio_extra() Kefeng Wang
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
Use newfolio/folio for migrate_folio_extra()/migrate_folio() to
save three compound_head() calls.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 mm/migrate_device.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index b6c27c76e1a0..d49a48d87d72 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -694,6 +694,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 		struct page *newpage = migrate_pfn_to_page(dst_pfns[i]);
 		struct page *page = migrate_pfn_to_page(src_pfns[i]);
 		struct address_space *mapping;
+		struct folio *newfolio, *folio;
 		int r;
 
 		if (!newpage) {
@@ -729,13 +730,12 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 		}
 
 		mapping = page_mapping(page);
+		folio = page_folio(page);
+		newfolio = page_folio(newpage);
 
-		if (is_device_private_page(newpage) ||
-		    is_device_coherent_page(newpage)) {
+		if (folio_is_device_private(newfolio) ||
+		    folio_is_device_coherent(newfolio)) {
 			if (mapping) {
-				struct folio *folio;
-
-				folio = page_folio(page);
 
 				/*
 				 * For now only support anonymous memory migrating to
@@ -749,7 +749,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 					continue;
 				}
 			}
-		} else if (is_zone_device_page(newpage)) {
+		} else if (folio_is_zone_device(newfolio)) {
 			/*
 			 * Other types of ZONE_DEVICE page are not supported.
 			 */
@@ -758,12 +758,11 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 		}
 
 		if (migrate && migrate->fault_page == page)
-			r = migrate_folio_extra(mapping, page_folio(newpage),
-						page_folio(page),
+			r = migrate_folio_extra(mapping, newfolio, folio,
 						MIGRATE_SYNC_NO_COPY, 1);
 		else
-			r = migrate_folio(mapping, page_folio(newpage),
-					page_folio(page), MIGRATE_SYNC_NO_COPY);
+			r = migrate_folio(mapping, newfolio, folio,
+					  MIGRATE_SYNC_NO_COPY);
 		if (r != MIGRATEPAGE_SUCCESS)
 			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
 	}
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * Re: [PATCH rfc 2/9] mm: migrate_device: use more folio in __migrate_device_pages()
  2024-01-29  7:09 ` [PATCH rfc 2/9] mm: migrate_device: use more folio in __migrate_device_pages() Kefeng Wang
@ 2024-02-01 19:27   ` Matthew Wilcox
  2024-02-02  2:44     ` Kefeng Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Matthew Wilcox @ 2024-02-01 19:27 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On Mon, Jan 29, 2024 at 03:09:27PM +0800, Kefeng Wang wrote:
> Use newfolio/folio for migrate_folio_extra()/migrate_folio() to
> save three compound_head() calls.
I've looked at this function before and I get stuck on the question of
whether a device page truly is a folio or not.  I think for the moment,
we've decided that it is, so ..
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Although ...
> @@ -729,13 +730,12 @@ static void __migrate_device_pages(unsigned long *src_pfns,
>  		}
>  
>  		mapping = page_mapping(page);
> +		folio = page_folio(page);
> +		newfolio = page_folio(newpage);
you should save one more call to compound_head() by changing the
page_mapping() to folio_mapping().
^ permalink raw reply	[flat|nested] 19+ messages in thread 
- * Re: [PATCH rfc 2/9] mm: migrate_device: use more folio in __migrate_device_pages()
  2024-02-01 19:27   ` Matthew Wilcox
@ 2024-02-02  2:44     ` Kefeng Wang
  0 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-02-02  2:44 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On 2024/2/2 3:27, Matthew Wilcox wrote:
> On Mon, Jan 29, 2024 at 03:09:27PM +0800, Kefeng Wang wrote:
>> Use newfolio/folio for migrate_folio_extra()/migrate_folio() to
>> save three compound_head() calls.
> 
> I've looked at this function before and I get stuck on the question of
> whether a device page truly is a folio or not.  I think for the moment,
> we've decided that it is, so ..
> 
> Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> 
> Although ...
> 
>> @@ -729,13 +730,12 @@ static void __migrate_device_pages(unsigned long *src_pfns,
>>   		}
>>   
>>   		mapping = page_mapping(page);
>> +		folio = page_folio(page);
>> +		newfolio = page_folio(newpage);
> 
> you should save one more call to compound_head() by changing the
> page_mapping() to folio_mapping().
Missing this one, will update, thanks.
> 
^ permalink raw reply	[flat|nested] 19+ messages in thread 
 
 
- * [PATCH rfc 3/9] mm: migrate: remove migrate_folio_extra()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 1/9] mm: migrate: simplify __buffer_migrate_folio() Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 2/9] mm: migrate_device: use more folio in __migrate_device_pages() Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-02-01 20:09   ` Matthew Wilcox
  2024-01-29  7:09 ` [PATCH rfc 4/9] mm: remove MIGRATE_SYNC_NO_COPY mode Kefeng Wang
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
Convert migrate_folio_extra() to __migrate_folio() which will be used
by migrate_folio() and filemap_migrate_folio(), also directly call
folio_migrate_mapping() in __migrate_device_pages() to simplify code.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 include/linux/migrate.h |  2 --
 mm/migrate.c            | 32 +++++++++++---------------------
 mm/migrate_device.c     | 13 +++++++------
 3 files changed, 18 insertions(+), 29 deletions(-)
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 2ce13e8a309b..517f70b70620 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -63,8 +63,6 @@ extern const char *migrate_reason_names[MR_TYPES];
 #ifdef CONFIG_MIGRATION
 
 void putback_movable_pages(struct list_head *l);
-int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
-		struct folio *src, enum migrate_mode mode, int extra_count);
 int migrate_folio(struct address_space *mapping, struct folio *dst,
 		struct folio *src, enum migrate_mode mode);
 int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free,
diff --git a/mm/migrate.c b/mm/migrate.c
index cdae25b7105f..a51ceebbe3b1 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -655,22 +655,24 @@ EXPORT_SYMBOL(folio_migrate_copy);
  *                    Migration functions
  ***********************************************************/
 
-int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
-		struct folio *src, enum migrate_mode mode, int extra_count)
+static int __migrate_folio(struct address_space *mapping, struct folio *dst,
+			   struct folio *src, enum migrate_mode mode,
+			   void *src_private)
 {
 	int rc;
 
-	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
-
-	rc = folio_migrate_mapping(mapping, dst, src, extra_count);
-
+	rc = folio_migrate_mapping(mapping, dst, src, 0);
 	if (rc != MIGRATEPAGE_SUCCESS)
 		return rc;
 
+	if (src_private)
+		folio_attach_private(dst, folio_detach_private(src));
+
 	if (mode != MIGRATE_SYNC_NO_COPY)
 		folio_migrate_copy(dst, src);
 	else
 		folio_migrate_flags(dst, src);
+
 	return MIGRATEPAGE_SUCCESS;
 }
 
@@ -689,7 +691,8 @@ int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
 int migrate_folio(struct address_space *mapping, struct folio *dst,
 		struct folio *src, enum migrate_mode mode)
 {
-	return migrate_folio_extra(mapping, dst, src, mode, 0);
+	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
+	return __migrate_folio(mapping, dst, src, mode, NULL);
 }
 EXPORT_SYMBOL(migrate_folio);
 
@@ -843,20 +846,7 @@ EXPORT_SYMBOL_GPL(buffer_migrate_folio_norefs);
 int filemap_migrate_folio(struct address_space *mapping,
 		struct folio *dst, struct folio *src, enum migrate_mode mode)
 {
-	int ret;
-
-	ret = folio_migrate_mapping(mapping, dst, src, 0);
-	if (ret != MIGRATEPAGE_SUCCESS)
-		return ret;
-
-	if (folio_get_private(src))
-		folio_attach_private(dst, folio_detach_private(src));
-
-	if (mode != MIGRATE_SYNC_NO_COPY)
-		folio_migrate_copy(dst, src);
-	else
-		folio_migrate_flags(dst, src);
-	return MIGRATEPAGE_SUCCESS;
+	return __migrate_folio(mapping, dst, src, mode, folio_get_private(src));
 }
 EXPORT_SYMBOL_GPL(filemap_migrate_folio);
 
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index d49a48d87d72..bea71d69295a 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -695,7 +695,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 		struct page *page = migrate_pfn_to_page(src_pfns[i]);
 		struct address_space *mapping;
 		struct folio *newfolio, *folio;
-		int r;
+		int r, extra_cnt = 0;
 
 		if (!newpage) {
 			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
@@ -757,14 +757,15 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 			continue;
 		}
 
+		BUG_ON(folio_test_writeback(folio));
+
 		if (migrate && migrate->fault_page == page)
-			r = migrate_folio_extra(mapping, newfolio, folio,
-						MIGRATE_SYNC_NO_COPY, 1);
-		else
-			r = migrate_folio(mapping, newfolio, folio,
-					  MIGRATE_SYNC_NO_COPY);
+			extra_cnt = 1;
+		r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);
 		if (r != MIGRATEPAGE_SUCCESS)
 			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
+		else
+			folio_migrate_flags(newfolio, folio);
 	}
 
 	if (notified)
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * Re: [PATCH rfc 3/9] mm: migrate: remove migrate_folio_extra()
  2024-01-29  7:09 ` [PATCH rfc 3/9] mm: migrate: remove migrate_folio_extra() Kefeng Wang
@ 2024-02-01 20:09   ` Matthew Wilcox
  2024-02-02  2:46     ` Kefeng Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Matthew Wilcox @ 2024-02-01 20:09 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On Mon, Jan 29, 2024 at 03:09:28PM +0800, Kefeng Wang wrote:
> Convert migrate_folio_extra() to __migrate_folio() which will be used
> by migrate_folio() and filemap_migrate_folio(), also directly call
> folio_migrate_mapping() in __migrate_device_pages() to simplify code.
This feels like two patches?  First convert __migrate_device_pages()
then do the other thing?
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
>  include/linux/migrate.h |  2 --
>  mm/migrate.c            | 32 +++++++++++---------------------
>  mm/migrate_device.c     | 13 +++++++------
>  3 files changed, 18 insertions(+), 29 deletions(-)
> 
> diff --git a/include/linux/migrate.h b/include/linux/migrate.h
> index 2ce13e8a309b..517f70b70620 100644
> --- a/include/linux/migrate.h
> +++ b/include/linux/migrate.h
> @@ -63,8 +63,6 @@ extern const char *migrate_reason_names[MR_TYPES];
>  #ifdef CONFIG_MIGRATION
>  
>  void putback_movable_pages(struct list_head *l);
> -int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
> -		struct folio *src, enum migrate_mode mode, int extra_count);
>  int migrate_folio(struct address_space *mapping, struct folio *dst,
>  		struct folio *src, enum migrate_mode mode);
>  int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free,
> diff --git a/mm/migrate.c b/mm/migrate.c
> index cdae25b7105f..a51ceebbe3b1 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -655,22 +655,24 @@ EXPORT_SYMBOL(folio_migrate_copy);
>   *                    Migration functions
>   ***********************************************************/
>  
> -int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
> -		struct folio *src, enum migrate_mode mode, int extra_count)
> +static int __migrate_folio(struct address_space *mapping, struct folio *dst,
> +			   struct folio *src, enum migrate_mode mode,
> +			   void *src_private)
>  {
>  	int rc;
>  
> -	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
> -
> -	rc = folio_migrate_mapping(mapping, dst, src, extra_count);
> -
> +	rc = folio_migrate_mapping(mapping, dst, src, 0);
>  	if (rc != MIGRATEPAGE_SUCCESS)
>  		return rc;
>  
> +	if (src_private)
> +		folio_attach_private(dst, folio_detach_private(src));
> +
>  	if (mode != MIGRATE_SYNC_NO_COPY)
>  		folio_migrate_copy(dst, src);
>  	else
>  		folio_migrate_flags(dst, src);
> +
>  	return MIGRATEPAGE_SUCCESS;
>  }
>  
> @@ -689,7 +691,8 @@ int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
>  int migrate_folio(struct address_space *mapping, struct folio *dst,
>  		struct folio *src, enum migrate_mode mode)
>  {
> -	return migrate_folio_extra(mapping, dst, src, mode, 0);
> +	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
> +	return __migrate_folio(mapping, dst, src, mode, NULL);
>  }
>  EXPORT_SYMBOL(migrate_folio);
>  
> @@ -843,20 +846,7 @@ EXPORT_SYMBOL_GPL(buffer_migrate_folio_norefs);
>  int filemap_migrate_folio(struct address_space *mapping,
>  		struct folio *dst, struct folio *src, enum migrate_mode mode)
>  {
> -	int ret;
> -
> -	ret = folio_migrate_mapping(mapping, dst, src, 0);
> -	if (ret != MIGRATEPAGE_SUCCESS)
> -		return ret;
> -
> -	if (folio_get_private(src))
> -		folio_attach_private(dst, folio_detach_private(src));
> -
> -	if (mode != MIGRATE_SYNC_NO_COPY)
> -		folio_migrate_copy(dst, src);
> -	else
> -		folio_migrate_flags(dst, src);
> -	return MIGRATEPAGE_SUCCESS;
> +	return __migrate_folio(mapping, dst, src, mode, folio_get_private(src));
>  }
>  EXPORT_SYMBOL_GPL(filemap_migrate_folio);
>  
> diff --git a/mm/migrate_device.c b/mm/migrate_device.c
> index d49a48d87d72..bea71d69295a 100644
> --- a/mm/migrate_device.c
> +++ b/mm/migrate_device.c
> @@ -695,7 +695,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
>  		struct page *page = migrate_pfn_to_page(src_pfns[i]);
>  		struct address_space *mapping;
>  		struct folio *newfolio, *folio;
> -		int r;
> +		int r, extra_cnt = 0;
>  
>  		if (!newpage) {
>  			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
> @@ -757,14 +757,15 @@ static void __migrate_device_pages(unsigned long *src_pfns,
>  			continue;
>  		}
>  
> +		BUG_ON(folio_test_writeback(folio));
> +
>  		if (migrate && migrate->fault_page == page)
> -			r = migrate_folio_extra(mapping, newfolio, folio,
> -						MIGRATE_SYNC_NO_COPY, 1);
> -		else
> -			r = migrate_folio(mapping, newfolio, folio,
> -					  MIGRATE_SYNC_NO_COPY);
> +			extra_cnt = 1;
> +		r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);
>  		if (r != MIGRATEPAGE_SUCCESS)
>  			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
> +		else
> +			folio_migrate_flags(newfolio, folio);
>  	}
>  
>  	if (notified)
> -- 
> 2.27.0
> 
^ permalink raw reply	[flat|nested] 19+ messages in thread
- * Re: [PATCH rfc 3/9] mm: migrate: remove migrate_folio_extra()
  2024-02-01 20:09   ` Matthew Wilcox
@ 2024-02-02  2:46     ` Kefeng Wang
  0 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-02-02  2:46 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On 2024/2/2 4:09, Matthew Wilcox wrote:
> On Mon, Jan 29, 2024 at 03:09:28PM +0800, Kefeng Wang wrote:
>> Convert migrate_folio_extra() to __migrate_folio() which will be used
>> by migrate_folio() and filemap_migrate_folio(), also directly call
>> folio_migrate_mapping() in __migrate_device_pages() to simplify code.
> 
> This feels like two patches?  First convert __migrate_device_pages()
> then do the other thing?
That will be better, will split it, thanks
> 
>> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
>> ---
>>   include/linux/migrate.h |  2 --
>>   mm/migrate.c            | 32 +++++++++++---------------------
>>   mm/migrate_device.c     | 13 +++++++------
>>   3 files changed, 18 insertions(+), 29 deletions(-)
>>
>> diff --git a/include/linux/migrate.h b/include/linux/migrate.h
>> index 2ce13e8a309b..517f70b70620 100644
>> --- a/include/linux/migrate.h
>> +++ b/include/linux/migrate.h
>> @@ -63,8 +63,6 @@ extern const char *migrate_reason_names[MR_TYPES];
>>   #ifdef CONFIG_MIGRATION
>>   
>>   void putback_movable_pages(struct list_head *l);
>> -int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
>> -		struct folio *src, enum migrate_mode mode, int extra_count);
>>   int migrate_folio(struct address_space *mapping, struct folio *dst,
>>   		struct folio *src, enum migrate_mode mode);
>>   int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free,
>> diff --git a/mm/migrate.c b/mm/migrate.c
>> index cdae25b7105f..a51ceebbe3b1 100644
>> --- a/mm/migrate.c
>> +++ b/mm/migrate.c
>> @@ -655,22 +655,24 @@ EXPORT_SYMBOL(folio_migrate_copy);
>>    *                    Migration functions
>>    ***********************************************************/
>>   
>> -int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
>> -		struct folio *src, enum migrate_mode mode, int extra_count)
>> +static int __migrate_folio(struct address_space *mapping, struct folio *dst,
>> +			   struct folio *src, enum migrate_mode mode,
>> +			   void *src_private)
>>   {
>>   	int rc;
>>   
>> -	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
>> -
>> -	rc = folio_migrate_mapping(mapping, dst, src, extra_count);
>> -
>> +	rc = folio_migrate_mapping(mapping, dst, src, 0);
>>   	if (rc != MIGRATEPAGE_SUCCESS)
>>   		return rc;
>>   
>> +	if (src_private)
>> +		folio_attach_private(dst, folio_detach_private(src));
>> +
>>   	if (mode != MIGRATE_SYNC_NO_COPY)
>>   		folio_migrate_copy(dst, src);
>>   	else
>>   		folio_migrate_flags(dst, src);
>> +
>>   	return MIGRATEPAGE_SUCCESS;
>>   }
>>   
>> @@ -689,7 +691,8 @@ int migrate_folio_extra(struct address_space *mapping, struct folio *dst,
>>   int migrate_folio(struct address_space *mapping, struct folio *dst,
>>   		struct folio *src, enum migrate_mode mode)
>>   {
>> -	return migrate_folio_extra(mapping, dst, src, mode, 0);
>> +	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
>> +	return __migrate_folio(mapping, dst, src, mode, NULL);
>>   }
>>   EXPORT_SYMBOL(migrate_folio);
>>   
>> @@ -843,20 +846,7 @@ EXPORT_SYMBOL_GPL(buffer_migrate_folio_norefs);
>>   int filemap_migrate_folio(struct address_space *mapping,
>>   		struct folio *dst, struct folio *src, enum migrate_mode mode)
>>   {
>> -	int ret;
>> -
>> -	ret = folio_migrate_mapping(mapping, dst, src, 0);
>> -	if (ret != MIGRATEPAGE_SUCCESS)
>> -		return ret;
>> -
>> -	if (folio_get_private(src))
>> -		folio_attach_private(dst, folio_detach_private(src));
>> -
>> -	if (mode != MIGRATE_SYNC_NO_COPY)
>> -		folio_migrate_copy(dst, src);
>> -	else
>> -		folio_migrate_flags(dst, src);
>> -	return MIGRATEPAGE_SUCCESS;
>> +	return __migrate_folio(mapping, dst, src, mode, folio_get_private(src));
>>   }
>>   EXPORT_SYMBOL_GPL(filemap_migrate_folio);
>>   
>> diff --git a/mm/migrate_device.c b/mm/migrate_device.c
>> index d49a48d87d72..bea71d69295a 100644
>> --- a/mm/migrate_device.c
>> +++ b/mm/migrate_device.c
>> @@ -695,7 +695,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
>>   		struct page *page = migrate_pfn_to_page(src_pfns[i]);
>>   		struct address_space *mapping;
>>   		struct folio *newfolio, *folio;
>> -		int r;
>> +		int r, extra_cnt = 0;
>>   
>>   		if (!newpage) {
>>   			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
>> @@ -757,14 +757,15 @@ static void __migrate_device_pages(unsigned long *src_pfns,
>>   			continue;
>>   		}
>>   
>> +		BUG_ON(folio_test_writeback(folio));
>> +
>>   		if (migrate && migrate->fault_page == page)
>> -			r = migrate_folio_extra(mapping, newfolio, folio,
>> -						MIGRATE_SYNC_NO_COPY, 1);
>> -		else
>> -			r = migrate_folio(mapping, newfolio, folio,
>> -					  MIGRATE_SYNC_NO_COPY);
>> +			extra_cnt = 1;
>> +		r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);
>>   		if (r != MIGRATEPAGE_SUCCESS)
>>   			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
>> +		else
>> +			folio_migrate_flags(newfolio, folio);
>>   	}
>>   
>>   	if (notified)
>> -- 
>> 2.27.0
>>
^ permalink raw reply	[flat|nested] 19+ messages in thread
 
 
- * [PATCH rfc 4/9] mm: remove MIGRATE_SYNC_NO_COPY mode
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
                   ` (2 preceding siblings ...)
  2024-01-29  7:09 ` [PATCH rfc 3/9] mm: migrate: remove migrate_folio_extra() Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-02-01 20:23   ` Matthew Wilcox
  2024-01-29  7:09 ` [PATCH rfc 5/9] mm: add folio_mc_copy() Kefeng Wang
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
Commit 2916ecc0f9d4 ("mm/migrate: new migrate mode MIGRATE_SYNC_NO_COPY")
introduce a new MIGRATE_SYNC_NO_COPY mode to allow to offload the copy to
a device DMA engine, which is only used __migrate_device_pages() to decide
whether or not copy the old page, and the MIGRATE_SYNC_NO_COPY mode only
set in hmm, as the MIGRATE_SYNC_NO_COPY set is removed by previous cleanup,
it seems that we could remove the unnecessary MIGRATE_SYNC_NO_COPY.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/aio.c                     | 12 +-----------
 fs/hugetlbfs/inode.c         |  5 +----
 include/linux/migrate_mode.h |  5 -----
 mm/balloon_compaction.c      |  8 --------
 mm/migrate.c                 |  8 +-------
 mm/zsmalloc.c                |  8 --------
 6 files changed, 3 insertions(+), 43 deletions(-)
diff --git a/fs/aio.c b/fs/aio.c
index bb2ff48991f3..1d0ca2a2776d 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -409,17 +409,7 @@ static int aio_migrate_folio(struct address_space *mapping, struct folio *dst,
 	struct kioctx *ctx;
 	unsigned long flags;
 	pgoff_t idx;
-	int rc;
-
-	/*
-	 * We cannot support the _NO_COPY case here, because copy needs to
-	 * happen under the ctx->completion_lock. That does not work with the
-	 * migration workflow of MIGRATE_SYNC_NO_COPY.
-	 */
-	if (mode == MIGRATE_SYNC_NO_COPY)
-		return -EINVAL;
-
-	rc = 0;
+	int rc = 0;
 
 	/* mapping->i_private_lock here protects against the kioctx teardown.  */
 	spin_lock(&mapping->i_private_lock);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index ee13c2ca8ad2..52839ffdd9a1 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1129,10 +1129,7 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
 		hugetlb_set_folio_subpool(src, NULL);
 	}
 
-	if (mode != MIGRATE_SYNC_NO_COPY)
-		folio_migrate_copy(dst, src);
-	else
-		folio_migrate_flags(dst, src);
+	folio_migrate_copy(dst, src);
 
 	return MIGRATEPAGE_SUCCESS;
 }
diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h
index f37cc03f9369..9fb482bb7323 100644
--- a/include/linux/migrate_mode.h
+++ b/include/linux/migrate_mode.h
@@ -7,16 +7,11 @@
  *	on most operations but not ->writepage as the potential stall time
  *	is too significant
  * MIGRATE_SYNC will block when migrating pages
- * MIGRATE_SYNC_NO_COPY will block when migrating pages but will not copy pages
- *	with the CPU. Instead, page copy happens outside the migratepage()
- *	callback and is likely using a DMA engine. See migrate_vma() and HMM
- *	(mm/hmm.c) for users of this mode.
  */
 enum migrate_mode {
 	MIGRATE_ASYNC,
 	MIGRATE_SYNC_LIGHT,
 	MIGRATE_SYNC,
-	MIGRATE_SYNC_NO_COPY,
 };
 
 enum migrate_reason {
diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c
index 22c96fed70b5..6597ebea8ae2 100644
--- a/mm/balloon_compaction.c
+++ b/mm/balloon_compaction.c
@@ -234,14 +234,6 @@ static int balloon_page_migrate(struct page *newpage, struct page *page,
 {
 	struct balloon_dev_info *balloon = balloon_page_device(page);
 
-	/*
-	 * We can not easily support the no copy case here so ignore it as it
-	 * is unlikely to be used with balloon pages. See include/linux/hmm.h
-	 * for a user of the MIGRATE_SYNC_NO_COPY mode.
-	 */
-	if (mode == MIGRATE_SYNC_NO_COPY)
-		return -EINVAL;
-
 	VM_BUG_ON_PAGE(!PageLocked(page), page);
 	VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
 
diff --git a/mm/migrate.c b/mm/migrate.c
index a51ceebbe3b1..107965bbc852 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -668,10 +668,7 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst,
 	if (src_private)
 		folio_attach_private(dst, folio_detach_private(src));
 
-	if (mode != MIGRATE_SYNC_NO_COPY)
-		folio_migrate_copy(dst, src);
-	else
-		folio_migrate_flags(dst, src);
+	folio_migrate_copy(dst, src);
 
 	return MIGRATEPAGE_SUCCESS;
 }
@@ -901,7 +898,6 @@ static int fallback_migrate_folio(struct address_space *mapping,
 		/* Only writeback folios in full synchronous migration */
 		switch (mode) {
 		case MIGRATE_SYNC:
-		case MIGRATE_SYNC_NO_COPY:
 			break;
 		default:
 			return -EBUSY;
@@ -1159,7 +1155,6 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
 		 */
 		switch (mode) {
 		case MIGRATE_SYNC:
-		case MIGRATE_SYNC_NO_COPY:
 			break;
 		default:
 			rc = -EBUSY;
@@ -1370,7 +1365,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
 			goto out;
 		switch (mode) {
 		case MIGRATE_SYNC:
-		case MIGRATE_SYNC_NO_COPY:
 			break;
 		default:
 			goto out;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index c937635e0ad1..b9ffe1a041ca 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1811,14 +1811,6 @@ static int zs_page_migrate(struct page *newpage, struct page *page,
 	unsigned long old_obj, new_obj;
 	unsigned int obj_idx;
 
-	/*
-	 * We cannot support the _NO_COPY case here, because copy needs to
-	 * happen under the zs lock, which does not work with
-	 * MIGRATE_SYNC_NO_COPY workflow.
-	 */
-	if (mode == MIGRATE_SYNC_NO_COPY)
-		return -EINVAL;
-
 	VM_BUG_ON_PAGE(!PageIsolated(page), page);
 
 	/* The page is locked, so this pointer must remain valid */
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * Re: [PATCH rfc 4/9] mm: remove MIGRATE_SYNC_NO_COPY mode
  2024-01-29  7:09 ` [PATCH rfc 4/9] mm: remove MIGRATE_SYNC_NO_COPY mode Kefeng Wang
@ 2024-02-01 20:23   ` Matthew Wilcox
  0 siblings, 0 replies; 19+ messages in thread
From: Matthew Wilcox @ 2024-02-01 20:23 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On Mon, Jan 29, 2024 at 03:09:29PM +0800, Kefeng Wang wrote:
> Commit 2916ecc0f9d4 ("mm/migrate: new migrate mode MIGRATE_SYNC_NO_COPY")
> introduce a new MIGRATE_SYNC_NO_COPY mode to allow to offload the copy to
> a device DMA engine, which is only used __migrate_device_pages() to decide
> whether or not copy the old page, and the MIGRATE_SYNC_NO_COPY mode only
> set in hmm, as the MIGRATE_SYNC_NO_COPY set is removed by previous cleanup,
> it seems that we could remove the unnecessary MIGRATE_SYNC_NO_COPY.
Ah!  I didn't understand the point of what you were doing in the
previous patch.  Now it makes a lot more sense.  This is a big
improvement, thanks!
^ permalink raw reply	[flat|nested] 19+ messages in thread
 
- * [PATCH rfc 5/9] mm: add folio_mc_copy()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
                   ` (3 preceding siblings ...)
  2024-01-29  7:09 ` [PATCH rfc 4/9] mm: remove MIGRATE_SYNC_NO_COPY mode Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio Kefeng Wang
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
Add a variant of folio_copy() which use copy_mc_highpage() to support
machine check safe copy when folio copy.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 include/linux/mm.h |  1 +
 mm/util.c          | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ac6b71cbdffb..fffa6025d8f9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1300,6 +1300,7 @@ void put_pages_list(struct list_head *pages);
 
 void split_page(struct page *page, unsigned int order);
 void folio_copy(struct folio *dst, struct folio *src);
+int folio_mc_copy(struct folio *dst, struct folio *src);
 
 unsigned long nr_free_buffer_pages(void);
 
diff --git a/mm/util.c b/mm/util.c
index 5faf3adc6f43..63e6e644eb5a 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -828,6 +828,26 @@ void folio_copy(struct folio *dst, struct folio *src)
 }
 EXPORT_SYMBOL(folio_copy);
 
+int folio_mc_copy(struct folio *dst, struct folio *src)
+{
+	long nr = folio_nr_pages(src);
+	long i = 0;
+	int ret = 0;
+
+	for (;;) {
+		if (copy_mc_highpage(folio_page(dst, i), folio_page(src, i))) {
+			ret = -EFAULT;
+			break;
+		}
+		if (++i == nr)
+			break;
+		cond_resched();
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(folio_mc_copy);
+
 int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS;
 int sysctl_overcommit_ratio __read_mostly = 50;
 unsigned long sysctl_overcommit_kbytes __read_mostly;
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
                   ` (4 preceding siblings ...)
  2024-01-29  7:09 ` [PATCH rfc 5/9] mm: add folio_mc_copy() Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-02-01 20:34   ` Matthew Wilcox
  2024-01-29  7:09 ` [PATCH rfc 7/9] fs: hugetlbfs: support poison recover from hugetlbfs_migrate_folio() Kefeng Wang
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
In order to support poisoned folio copy recover from migrate folio,
let's use folio_mc_copy() and move it in the begin of the function
of __migrate_folio(), which could simply error handling since there
is no turning back if folio_migrate_mapping() return success, the
downside is the folio copied even though folio_migrate_mapping()
return fail, a small optimization is to check whether folio does
not have extra refs before we do more work ahead in __migrate_folio(),
which could help us avoid unnecessary folio copy.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 mm/migrate.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 107965bbc852..99286394b5e5 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -661,6 +661,14 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst,
 {
 	int rc;
 
+	/* Check whether src does not have extra refs before we do more work */
+	if (folio_ref_count(src) != folio_expected_refs(mapping, src))
+		return -EAGAIN;
+
+	rc = folio_mc_copy(dst, src);
+	if (rc)
+		return rc;
+
 	rc = folio_migrate_mapping(mapping, dst, src, 0);
 	if (rc != MIGRATEPAGE_SUCCESS)
 		return rc;
@@ -668,7 +676,7 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst,
 	if (src_private)
 		folio_attach_private(dst, folio_detach_private(src));
 
-	folio_migrate_copy(dst, src);
+	folio_migrate_flags(dst, src);
 
 	return MIGRATEPAGE_SUCCESS;
 }
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * Re: [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio
  2024-01-29  7:09 ` [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio Kefeng Wang
@ 2024-02-01 20:34   ` Matthew Wilcox
  2024-02-02  3:04     ` Kefeng Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Matthew Wilcox @ 2024-02-01 20:34 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On Mon, Jan 29, 2024 at 03:09:31PM +0800, Kefeng Wang wrote:
> In order to support poisoned folio copy recover from migrate folio,
> let's use folio_mc_copy() and move it in the begin of the function
> of __migrate_folio(), which could simply error handling since there
> is no turning back if folio_migrate_mapping() return success, the
> downside is the folio copied even though folio_migrate_mapping()
> return fail, a small optimization is to check whether folio does
> not have extra refs before we do more work ahead in __migrate_folio(),
> which could help us avoid unnecessary folio copy.
OK, I see why you've done it this way.
Would it make more sense if we pulled the folio refcount freezing
out of folio_migrate_mapping() into its callers?  That way
folio_migrate_mapping() could never fail.
^ permalink raw reply	[flat|nested] 19+ messages in thread 
- * Re: [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio
  2024-02-01 20:34   ` Matthew Wilcox
@ 2024-02-02  3:04     ` Kefeng Wang
  2024-02-02  9:06       ` Kefeng Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Kefeng Wang @ 2024-02-02  3:04 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On 2024/2/2 4:34, Matthew Wilcox wrote:
> On Mon, Jan 29, 2024 at 03:09:31PM +0800, Kefeng Wang wrote:
>> In order to support poisoned folio copy recover from migrate folio,
>> let's use folio_mc_copy() and move it in the begin of the function
>> of __migrate_folio(), which could simply error handling since there
>> is no turning back if folio_migrate_mapping() return success, the
>> downside is the folio copied even though folio_migrate_mapping()
>> return fail, a small optimization is to check whether folio does
>> not have extra refs before we do more work ahead in __migrate_folio(),
>> which could help us avoid unnecessary folio copy.
> 
> OK, I see why you've done it this way.
> 
> Would it make more sense if we pulled the folio refcount freezing
> out of folio_migrate_mapping() into its callers?  That way
> folio_migrate_mapping() could never fail.
Will try this way, thank.
^ permalink raw reply	[flat|nested] 19+ messages in thread 
- * Re: [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio
  2024-02-02  3:04     ` Kefeng Wang
@ 2024-02-02  9:06       ` Kefeng Wang
  0 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-02-02  9:06 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Andrew Morton, linux-mm, Tony Luck, Naoya Horiguchi, Miaohe Lin,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel
On 2024/2/2 11:04, Kefeng Wang wrote:
> 
> 
> On 2024/2/2 4:34, Matthew Wilcox wrote:
>> On Mon, Jan 29, 2024 at 03:09:31PM +0800, Kefeng Wang wrote:
>>> In order to support poisoned folio copy recover from migrate folio,
>>> let's use folio_mc_copy() and move it in the begin of the function
>>> of __migrate_folio(), which could simply error handling since there
>>> is no turning back if folio_migrate_mapping() return success, the
>>> downside is the folio copied even though folio_migrate_mapping()
>>> return fail, a small optimization is to check whether folio does
>>> not have extra refs before we do more work ahead in __migrate_folio(),
>>> which could help us avoid unnecessary folio copy.
>>
>> OK, I see why you've done it this way.
>>
>> Would it make more sense if we pulled the folio refcount freezing
>> out of folio_migrate_mapping() into its callers?  That way
>> folio_migrate_mapping() could never fail.
> 
Question, the folio ref freezing is under the xas_lock_irq(), it can't
be moved out of lock, and if with xas lock irq, we couldn't call
folio_mc_copy(), so the above way is not feasible, or maybe I missing
something?
^ permalink raw reply	[flat|nested] 19+ messages in thread 
 
 
 
- * [PATCH rfc 7/9] fs: hugetlbfs: support poison recover from hugetlbfs_migrate_folio()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
                   ` (5 preceding siblings ...)
  2024-01-29  7:09 ` [PATCH rfc 6/9] mm: migrate: support poisoned recover from migrate folio Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 8/9] mm: migrate: remove folio_migrate_copy() Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 9/9] fs: aio: add explicit check for large folio in aio_migrate_folio() Kefeng Wang
  8 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
This is similar to __migrate_folio(), use folio_mc_copy() to avoid
panic when copy poisoned folio.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/hugetlbfs/inode.c    | 10 +++++++++-
 include/linux/migrate.h |  1 +
 mm/migrate.c            |  3 +--
 3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 52839ffdd9a1..3871968d1780 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1119,6 +1119,14 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
 {
 	int rc;
 
+	/* Check whether src does not have extra refs before we do more work */
+	if (folio_ref_count(src) != folio_expected_refs(mapping, src))
+		return -EAGAIN;
+
+	rc = folio_mc_copy(dst, src);
+	if (rc)
+		return rc;
+
 	rc = migrate_huge_page_move_mapping(mapping, dst, src);
 	if (rc != MIGRATEPAGE_SUCCESS)
 		return rc;
@@ -1129,7 +1137,7 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
 		hugetlb_set_folio_subpool(src, NULL);
 	}
 
-	folio_migrate_copy(dst, src);
+	folio_migrate_flags(dst, src);
 
 	return MIGRATEPAGE_SUCCESS;
 }
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 517f70b70620..ab387ea66365 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -79,6 +79,7 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio);
 void folio_migrate_copy(struct folio *newfolio, struct folio *folio);
 int folio_migrate_mapping(struct address_space *mapping,
 		struct folio *newfolio, struct folio *folio, int extra_count);
+int folio_expected_refs(struct address_space *mapping, struct folio *folio);
 
 #else
 
diff --git a/mm/migrate.c b/mm/migrate.c
index 99286394b5e5..097d67c82f8b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -375,8 +375,7 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
 }
 #endif
 
-static int folio_expected_refs(struct address_space *mapping,
-		struct folio *folio)
+int folio_expected_refs(struct address_space *mapping, struct folio *folio)
 {
 	int refs = 1;
 	if (!mapping)
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * [PATCH rfc 8/9] mm: migrate: remove folio_migrate_copy()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
                   ` (6 preceding siblings ...)
  2024-01-29  7:09 ` [PATCH rfc 7/9] fs: hugetlbfs: support poison recover from hugetlbfs_migrate_folio() Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  2024-01-29  7:09 ` [PATCH rfc 9/9] fs: aio: add explicit check for large folio in aio_migrate_folio() Kefeng Wang
  8 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
The folio_migrate_copy() is just a wrapper of folio_copy() and
folio_migrate_flags(), it is simple and only aio use it for now,
unfold it and remove folio_migrate_copy().
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/aio.c                | 3 ++-
 include/linux/migrate.h | 1 -
 mm/migrate.c            | 7 -------
 3 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/fs/aio.c b/fs/aio.c
index 1d0ca2a2776d..631e83eee5a1 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -454,7 +454,8 @@ static int aio_migrate_folio(struct address_space *mapping, struct folio *dst,
 	 * events from being lost.
 	 */
 	spin_lock_irqsave(&ctx->completion_lock, flags);
-	folio_migrate_copy(dst, src);
+	folio_copy(dst, src);
+	folio_migrate_flags(dst, src);
 	BUG_ON(ctx->ring_pages[idx] != &src->page);
 	ctx->ring_pages[idx] = &dst->page;
 	spin_unlock_irqrestore(&ctx->completion_lock, flags);
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index ab387ea66365..13fff8f7832b 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -76,7 +76,6 @@ int migrate_huge_page_move_mapping(struct address_space *mapping,
 void migration_entry_wait_on_locked(swp_entry_t entry, spinlock_t *ptl)
 		__releases(ptl);
 void folio_migrate_flags(struct folio *newfolio, struct folio *folio);
-void folio_migrate_copy(struct folio *newfolio, struct folio *folio);
 int folio_migrate_mapping(struct address_space *mapping,
 		struct folio *newfolio, struct folio *folio, int extra_count);
 int folio_expected_refs(struct address_space *mapping, struct folio *folio);
diff --git a/mm/migrate.c b/mm/migrate.c
index 097d67c82f8b..d5c1b1542335 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -643,13 +643,6 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio)
 }
 EXPORT_SYMBOL(folio_migrate_flags);
 
-void folio_migrate_copy(struct folio *newfolio, struct folio *folio)
-{
-	folio_copy(newfolio, folio);
-	folio_migrate_flags(newfolio, folio);
-}
-EXPORT_SYMBOL(folio_migrate_copy);
-
 /************************************************************
  *                    Migration functions
  ***********************************************************/
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread
- * [PATCH rfc 9/9] fs: aio: add explicit check for large folio in aio_migrate_folio()
  2024-01-29  7:09 [PATCH rfc 0/9] mm: migrate: support poison recover from migrate folio Kefeng Wang
                   ` (7 preceding siblings ...)
  2024-01-29  7:09 ` [PATCH rfc 8/9] mm: migrate: remove folio_migrate_copy() Kefeng Wang
@ 2024-01-29  7:09 ` Kefeng Wang
  8 siblings, 0 replies; 19+ messages in thread
From: Kefeng Wang @ 2024-01-29  7:09 UTC (permalink / raw)
  To: Andrew Morton, linux-mm
  Cc: Tony Luck, Naoya Horiguchi, Miaohe Lin, Matthew Wilcox,
	David Hildenbrand, Muchun Song, Benjamin LaHaise, jglisse,
	linux-aio, linux-fsdevel, Kefeng Wang
Since large folio copy could spend lots of time and it is involved with
a cond_resched(), the aio couldn't support migrate large folio as it takes
a spin lock when folio copy, add explicit check for large folio and return
err directly.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/aio.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/fs/aio.c b/fs/aio.c
index 631e83eee5a1..372f22b85b11 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -411,6 +411,10 @@ static int aio_migrate_folio(struct address_space *mapping, struct folio *dst,
 	pgoff_t idx;
 	int rc = 0;
 
+	/* Large folio aren't supported */
+	if (folio_test_large(src))
+		return -EINVAL;
+
 	/* mapping->i_private_lock here protects against the kioctx teardown.  */
 	spin_lock(&mapping->i_private_lock);
 	ctx = mapping->i_private_data;
-- 
2.27.0
^ permalink raw reply related	[flat|nested] 19+ messages in thread