diff mbox series

[rfc,6/9] mm: migrate: support poisoned recover from migrate folio

Message ID 20240129070934.3717659-7-wangkefeng.wang@huawei.com (mailing list archive)
State New
Headers show
Series mm: migrate: support poison recover from migrate folio | expand

Commit Message

Kefeng Wang Jan. 29, 2024, 7:09 a.m. UTC
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(-)

Comments

Matthew Wilcox Feb. 1, 2024, 8:34 p.m. UTC | #1
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.
Kefeng Wang Feb. 2, 2024, 3:04 a.m. UTC | #2
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.
Kefeng Wang Feb. 2, 2024, 9:06 a.m. UTC | #3
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?
diff mbox series

Patch

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;
 }