diff mbox series

[v5,3/4] mm,hwpoison: take free pages off the buddy freelists for hugetlb

Message ID 20201013144447.6706-4-osalvador@suse.de (mailing list archive)
State New, archived
Headers show
Series HWpoison: further fixes and cleanups | expand

Commit Message

Oscar Salvador Oct. 13, 2020, 2:44 p.m. UTC
Currently, free hugetlb get dissolved, but we also need to make sure
to take the poisoned subpage off the buddy frelists, so no one stumbles
upon it (see previous patch for more information).

Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
 mm/memory-failure.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

Comments

HORIGUCHI NAOYA(堀口 直也) Oct. 14, 2020, 12:05 a.m. UTC | #1
On Tue, Oct 13, 2020 at 04:44:46PM +0200, Oscar Salvador wrote:
> Currently, free hugetlb get dissolved, but we also need to make sure
> to take the poisoned subpage off the buddy frelists, so no one stumbles
> upon it (see previous patch for more information).
> 
> Signed-off-by: Oscar Salvador <osalvador@suse.de>

Acked-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
Vlastimil Babka Nov. 25, 2020, 4:36 p.m. UTC | #2
On 10/13/20 4:44 PM, Oscar Salvador wrote:
> Currently, free hugetlb get dissolved, but we also need to make sure
> to take the poisoned subpage off the buddy frelists, so no one stumbles
> upon it (see previous patch for more information).
> 
> Signed-off-by: Oscar Salvador <osalvador@suse.de>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

> ---
>   mm/memory-failure.c | 19 +++++++++++++------
>   1 file changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index 181bed890c16..30aadeca97d2 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -809,7 +809,7 @@ static int me_swapcache_clean(struct page *p, unsigned long pfn)
>    */
>   static int me_huge_page(struct page *p, unsigned long pfn)
>   {
> -	int res = 0;
> +	int res;
>   	struct page *hpage = compound_head(p);
>   	struct address_space *mapping;
>   
> @@ -820,6 +820,7 @@ static int me_huge_page(struct page *p, unsigned long pfn)
>   	if (mapping) {
>   		res = truncate_error_page(hpage, pfn, mapping);
>   	} else {
> +		res = MF_FAILED;
>   		unlock_page(hpage);
>   		/*
>   		 * migration entry prevents later access on error anonymous
> @@ -828,8 +829,10 @@ static int me_huge_page(struct page *p, unsigned long pfn)
>   		 */
>   		if (PageAnon(hpage))
>   			put_page(hpage);
> -		dissolve_free_huge_page(p);
> -		res = MF_RECOVERED;
> +		if (!dissolve_free_huge_page(p) && take_page_off_buddy(p)) {
> +			page_ref_inc(p);
> +			res = MF_RECOVERED;
> +		}
>   		lock_page(hpage);
>   	}
>   
> @@ -1198,9 +1201,13 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
>   			}
>   		}
>   		unlock_page(head);
> -		dissolve_free_huge_page(p);
> -		action_result(pfn, MF_MSG_FREE_HUGE, MF_DELAYED);
> -		return 0;
> +		res = MF_FAILED;
> +		if (!dissolve_free_huge_page(p) && take_page_off_buddy(p)) {
> +			page_ref_inc(p);
> +			res = MF_RECOVERED;
> +		}
> +		action_result(pfn, MF_MSG_FREE_HUGE, res);
> +		return res == MF_RECOVERED ? 0 : -EBUSY;
>   	}
>   
>   	lock_page(head);
>
diff mbox series

Patch

diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 181bed890c16..30aadeca97d2 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -809,7 +809,7 @@  static int me_swapcache_clean(struct page *p, unsigned long pfn)
  */
 static int me_huge_page(struct page *p, unsigned long pfn)
 {
-	int res = 0;
+	int res;
 	struct page *hpage = compound_head(p);
 	struct address_space *mapping;
 
@@ -820,6 +820,7 @@  static int me_huge_page(struct page *p, unsigned long pfn)
 	if (mapping) {
 		res = truncate_error_page(hpage, pfn, mapping);
 	} else {
+		res = MF_FAILED;
 		unlock_page(hpage);
 		/*
 		 * migration entry prevents later access on error anonymous
@@ -828,8 +829,10 @@  static int me_huge_page(struct page *p, unsigned long pfn)
 		 */
 		if (PageAnon(hpage))
 			put_page(hpage);
-		dissolve_free_huge_page(p);
-		res = MF_RECOVERED;
+		if (!dissolve_free_huge_page(p) && take_page_off_buddy(p)) {
+			page_ref_inc(p);
+			res = MF_RECOVERED;
+		}
 		lock_page(hpage);
 	}
 
@@ -1198,9 +1201,13 @@  static int memory_failure_hugetlb(unsigned long pfn, int flags)
 			}
 		}
 		unlock_page(head);
-		dissolve_free_huge_page(p);
-		action_result(pfn, MF_MSG_FREE_HUGE, MF_DELAYED);
-		return 0;
+		res = MF_FAILED;
+		if (!dissolve_free_huge_page(p) && take_page_off_buddy(p)) {
+			page_ref_inc(p);
+			res = MF_RECOVERED;
+		}
+		action_result(pfn, MF_MSG_FREE_HUGE, res);
+		return res == MF_RECOVERED ? 0 : -EBUSY;
 	}
 
 	lock_page(head);