All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] mm/page_alloc.c: cleanup on check page
@ 2020-01-19 13:14 Wei Yang
  2020-01-19 13:14 ` [PATCH 1/4] mm/page_alloc.c: extract commom part to " Wei Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Wei Yang @ 2020-01-19 13:14 UTC (permalink / raw)
  To: akpm; +Cc: linux-mm, linux-kernel, Wei Yang

The patch set does some cleanup related to check page:

* extract the common part to do check page 
* rename two functions for consistent name convention
* remove two unnecessary variable assignments

No functional change.

Wei Yang (4):
  mm/page_alloc.c: extract commom part to check page
  mm/page_alloc.c: rename free_pages_check_bad() to
    check_free_page_bad()
  mm/page_alloc.c: rename free_pages_check() to check_free_page()
  mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison

 mm/page_alloc.c | 50 ++++++++++++++++++++++---------------------------
 1 file changed, 22 insertions(+), 28 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/4] mm/page_alloc.c: extract commom part to check page
  2020-01-19 13:14 [PATCH 0/4] mm/page_alloc.c: cleanup on check page Wei Yang
@ 2020-01-19 13:14 ` Wei Yang
  2020-01-19 22:06     ` David Rientjes
  2020-01-19 13:14 ` [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad() Wei Yang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Yang @ 2020-01-19 13:14 UTC (permalink / raw)
  To: akpm; +Cc: linux-mm, linux-kernel, Wei Yang

During free and new page, we did some check on the status of page
struct.

There is some common part, just extract them.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
 mm/page_alloc.c | 36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d047bf7d8fd4..8cd06729169f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1025,13 +1025,9 @@ static inline bool page_expected_state(struct page *page,
 	return true;
 }
 
-static void free_pages_check_bad(struct page *page)
+static inline const char *__check_page(struct page *page)
 {
-	const char *bad_reason;
-	unsigned long bad_flags;
-
-	bad_reason = NULL;
-	bad_flags = 0;
+	const char *bad_reason = NULL;
 
 	if (unlikely(atomic_read(&page->_mapcount) != -1))
 		bad_reason = "nonzero mapcount";
@@ -1039,14 +1035,23 @@ static void free_pages_check_bad(struct page *page)
 		bad_reason = "non-NULL mapping";
 	if (unlikely(page_ref_count(page) != 0))
 		bad_reason = "nonzero _refcount";
-	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
-		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
-		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
-	}
 #ifdef CONFIG_MEMCG
 	if (unlikely(page->mem_cgroup))
 		bad_reason = "page still charged to cgroup";
 #endif
+	return bad_reason;
+}
+
+static void free_pages_check_bad(struct page *page)
+{
+	const char *bad_reason = NULL;
+	unsigned long bad_flags = 0;
+
+	bad_reason = __check_page(page);
+	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
+		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
+		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
+	}
 	bad_page(page, bad_reason, bad_flags);
 }
 
@@ -2044,12 +2049,7 @@ static void check_new_page_bad(struct page *page)
 	const char *bad_reason = NULL;
 	unsigned long bad_flags = 0;
 
-	if (unlikely(atomic_read(&page->_mapcount) != -1))
-		bad_reason = "nonzero mapcount";
-	if (unlikely(page->mapping != NULL))
-		bad_reason = "non-NULL mapping";
-	if (unlikely(page_ref_count(page) != 0))
-		bad_reason = "nonzero _refcount";
+	bad_reason = __check_page(page);
 	if (unlikely(page->flags & __PG_HWPOISON)) {
 		bad_reason = "HWPoisoned (hardware-corrupted)";
 		bad_flags = __PG_HWPOISON;
@@ -2061,10 +2061,6 @@ static void check_new_page_bad(struct page *page)
 		bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set";
 		bad_flags = PAGE_FLAGS_CHECK_AT_PREP;
 	}
-#ifdef CONFIG_MEMCG
-	if (unlikely(page->mem_cgroup))
-		bad_reason = "page still charged to cgroup";
-#endif
 	bad_page(page, bad_reason, bad_flags);
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad()
  2020-01-19 13:14 [PATCH 0/4] mm/page_alloc.c: cleanup on check page Wei Yang
  2020-01-19 13:14 ` [PATCH 1/4] mm/page_alloc.c: extract commom part to " Wei Yang
@ 2020-01-19 13:14 ` Wei Yang
  2020-01-19 22:07     ` David Rientjes
  2020-01-19 13:14 ` [PATCH 3/4] mm/page_alloc.c: rename free_pages_check() to check_free_page() Wei Yang
  2020-01-19 13:14 ` [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison Wei Yang
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Yang @ 2020-01-19 13:14 UTC (permalink / raw)
  To: akpm; +Cc: linux-mm, linux-kernel, Wei Yang

free_pages_check_bad() is the counterpart of check_new_page_bad(), while
their naming convention is a little different.

Use verb at first and singular form.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
 mm/page_alloc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8cd06729169f..e2324df1b261 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1042,7 +1042,7 @@ static inline const char *__check_page(struct page *page)
 	return bad_reason;
 }
 
-static void free_pages_check_bad(struct page *page)
+static void check_free_page_bad(struct page *page)
 {
 	const char *bad_reason = NULL;
 	unsigned long bad_flags = 0;
@@ -1061,7 +1061,7 @@ static inline int free_pages_check(struct page *page)
 		return 0;
 
 	/* Something has gone sideways, find it */
-	free_pages_check_bad(page);
+	check_free_page_bad(page);
 	return 1;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/4] mm/page_alloc.c: rename free_pages_check() to check_free_page()
  2020-01-19 13:14 [PATCH 0/4] mm/page_alloc.c: cleanup on check page Wei Yang
  2020-01-19 13:14 ` [PATCH 1/4] mm/page_alloc.c: extract commom part to " Wei Yang
  2020-01-19 13:14 ` [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad() Wei Yang
@ 2020-01-19 13:14 ` Wei Yang
  2020-01-19 13:14 ` [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison Wei Yang
  3 siblings, 0 replies; 13+ messages in thread
From: Wei Yang @ 2020-01-19 13:14 UTC (permalink / raw)
  To: akpm; +Cc: linux-mm, linux-kernel, Wei Yang

free_pages_check() is the counterpart of check_new_page(), while
their naming convention is a little different.

Use verb at first and singular form.

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
 mm/page_alloc.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e2324df1b261..87658a16af07 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1055,7 +1055,7 @@ static void check_free_page_bad(struct page *page)
 	bad_page(page, bad_reason, bad_flags);
 }
 
-static inline int free_pages_check(struct page *page)
+static inline int check_free_page(struct page *page)
 {
 	if (likely(page_expected_state(page, PAGE_FLAGS_CHECK_AT_FREE)))
 		return 0;
@@ -1147,7 +1147,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
 		for (i = 1; i < (1 << order); i++) {
 			if (compound)
 				bad += free_tail_pages_check(page, page + i);
-			if (unlikely(free_pages_check(page + i))) {
+			if (unlikely(check_free_page(page + i))) {
 				bad++;
 				continue;
 			}
@@ -1159,7 +1159,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
 	if (memcg_kmem_enabled() && PageKmemcg(page))
 		__memcg_kmem_uncharge(page, order);
 	if (check_free)
-		bad += free_pages_check(page);
+		bad += check_free_page(page);
 	if (bad)
 		return false;
 
@@ -1206,7 +1206,7 @@ static bool free_pcp_prepare(struct page *page)
 static bool bulkfree_pcp_prepare(struct page *page)
 {
 	if (debug_pagealloc_enabled_static())
-		return free_pages_check(page);
+		return check_free_page(page);
 	else
 		return false;
 }
@@ -1227,7 +1227,7 @@ static bool free_pcp_prepare(struct page *page)
 
 static bool bulkfree_pcp_prepare(struct page *page)
 {
-	return free_pages_check(page);
+	return check_free_page(page);
 }
 #endif /* CONFIG_DEBUG_VM */
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison
  2020-01-19 13:14 [PATCH 0/4] mm/page_alloc.c: cleanup on check page Wei Yang
                   ` (2 preceding siblings ...)
  2020-01-19 13:14 ` [PATCH 3/4] mm/page_alloc.c: rename free_pages_check() to check_free_page() Wei Yang
@ 2020-01-19 13:14 ` Wei Yang
  2020-01-19 22:07     ` David Rientjes
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Yang @ 2020-01-19 13:14 UTC (permalink / raw)
  To: akpm; +Cc: linux-mm, linux-kernel, Wei Yang

Since function returns directly, bad_[reason|flags] is not used any
where.

This is a following cleanup for commit e570f56cccd21 ("mm:
check_new_page_bad() directly returns in __PG_HWPOISON case")

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
 mm/page_alloc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 87658a16af07..2b5e2e156dbf 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2051,8 +2051,6 @@ static void check_new_page_bad(struct page *page)
 
 	bad_reason = __check_page(page);
 	if (unlikely(page->flags & __PG_HWPOISON)) {
-		bad_reason = "HWPoisoned (hardware-corrupted)";
-		bad_flags = __PG_HWPOISON;
 		/* Don't complain about hwpoisoned pages */
 		page_mapcount_reset(page); /* remove PageBuddy */
 		return;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/4] mm/page_alloc.c: extract commom part to check page
  2020-01-19 13:14 ` [PATCH 1/4] mm/page_alloc.c: extract commom part to " Wei Yang
@ 2020-01-19 22:06     ` David Rientjes
  0 siblings, 0 replies; 13+ messages in thread
From: David Rientjes @ 2020-01-19 22:06 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, linux-mm, linux-kernel

On Sun, 19 Jan 2020, Wei Yang wrote:

> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index d047bf7d8fd4..8cd06729169f 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -1025,13 +1025,9 @@ static inline bool page_expected_state(struct page *page,
>  	return true;
>  }
>  
> -static void free_pages_check_bad(struct page *page)
> +static inline const char *__check_page(struct page *page)
>  {
> -	const char *bad_reason;
> -	unsigned long bad_flags;
> -
> -	bad_reason = NULL;
> -	bad_flags = 0;
> +	const char *bad_reason = NULL;
>  
>  	if (unlikely(atomic_read(&page->_mapcount) != -1))
>  		bad_reason = "nonzero mapcount";
> @@ -1039,14 +1035,23 @@ static void free_pages_check_bad(struct page *page)
>  		bad_reason = "non-NULL mapping";
>  	if (unlikely(page_ref_count(page) != 0))
>  		bad_reason = "nonzero _refcount";
> -	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
> -		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
> -		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
> -	}
>  #ifdef CONFIG_MEMCG
>  	if (unlikely(page->mem_cgroup))
>  		bad_reason = "page still charged to cgroup";
>  #endif
> +	return bad_reason;
> +}
> +
> +static void free_pages_check_bad(struct page *page)
> +{
> +	const char *bad_reason = NULL;
> +	unsigned long bad_flags = 0;
> +
> +	bad_reason = __check_page(page);
> +	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
> +		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
> +		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
> +	}
>  	bad_page(page, bad_reason, bad_flags);
>  }
>  
> @@ -2044,12 +2049,7 @@ static void check_new_page_bad(struct page *page)
>  	const char *bad_reason = NULL;
>  	unsigned long bad_flags = 0;
>  
> -	if (unlikely(atomic_read(&page->_mapcount) != -1))
> -		bad_reason = "nonzero mapcount";
> -	if (unlikely(page->mapping != NULL))
> -		bad_reason = "non-NULL mapping";
> -	if (unlikely(page_ref_count(page) != 0))
> -		bad_reason = "nonzero _refcount";
> +	bad_reason = __check_page(page);
>  	if (unlikely(page->flags & __PG_HWPOISON)) {
>  		bad_reason = "HWPoisoned (hardware-corrupted)";
>  		bad_flags = __PG_HWPOISON;
> @@ -2061,10 +2061,6 @@ static void check_new_page_bad(struct page *page)
>  		bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set";
>  		bad_flags = PAGE_FLAGS_CHECK_AT_PREP;
>  	}
> -#ifdef CONFIG_MEMCG
> -	if (unlikely(page->mem_cgroup))
> -		bad_reason = "page still charged to cgroup";
> -#endif
>  	bad_page(page, bad_reason, bad_flags);
>  }
>  

I think this is compounding a previous problem in these functions: these 
are all "if" clauses, not "else if" clauses so they are presumably ordered 
based on least significant to most significant (we only see the last 
bad_reason that we find).  For the page->mem_cgroup check, this leaves 
bad_flags set but it doesn't match bad_reason.

Could you instead fix the problem with these functions so that we actually 
list *all* the problems with the page rather than only the last 
conditional that is true?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/4] mm/page_alloc.c: extract commom part to check page
@ 2020-01-19 22:06     ` David Rientjes
  0 siblings, 0 replies; 13+ messages in thread
From: David Rientjes @ 2020-01-19 22:06 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, linux-mm, linux-kernel

On Sun, 19 Jan 2020, Wei Yang wrote:

> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index d047bf7d8fd4..8cd06729169f 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -1025,13 +1025,9 @@ static inline bool page_expected_state(struct page *page,
>  	return true;
>  }
>  
> -static void free_pages_check_bad(struct page *page)
> +static inline const char *__check_page(struct page *page)
>  {
> -	const char *bad_reason;
> -	unsigned long bad_flags;
> -
> -	bad_reason = NULL;
> -	bad_flags = 0;
> +	const char *bad_reason = NULL;
>  
>  	if (unlikely(atomic_read(&page->_mapcount) != -1))
>  		bad_reason = "nonzero mapcount";
> @@ -1039,14 +1035,23 @@ static void free_pages_check_bad(struct page *page)
>  		bad_reason = "non-NULL mapping";
>  	if (unlikely(page_ref_count(page) != 0))
>  		bad_reason = "nonzero _refcount";
> -	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
> -		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
> -		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
> -	}
>  #ifdef CONFIG_MEMCG
>  	if (unlikely(page->mem_cgroup))
>  		bad_reason = "page still charged to cgroup";
>  #endif
> +	return bad_reason;
> +}
> +
> +static void free_pages_check_bad(struct page *page)
> +{
> +	const char *bad_reason = NULL;
> +	unsigned long bad_flags = 0;
> +
> +	bad_reason = __check_page(page);
> +	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
> +		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
> +		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
> +	}
>  	bad_page(page, bad_reason, bad_flags);
>  }
>  
> @@ -2044,12 +2049,7 @@ static void check_new_page_bad(struct page *page)
>  	const char *bad_reason = NULL;
>  	unsigned long bad_flags = 0;
>  
> -	if (unlikely(atomic_read(&page->_mapcount) != -1))
> -		bad_reason = "nonzero mapcount";
> -	if (unlikely(page->mapping != NULL))
> -		bad_reason = "non-NULL mapping";
> -	if (unlikely(page_ref_count(page) != 0))
> -		bad_reason = "nonzero _refcount";
> +	bad_reason = __check_page(page);
>  	if (unlikely(page->flags & __PG_HWPOISON)) {
>  		bad_reason = "HWPoisoned (hardware-corrupted)";
>  		bad_flags = __PG_HWPOISON;
> @@ -2061,10 +2061,6 @@ static void check_new_page_bad(struct page *page)
>  		bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set";
>  		bad_flags = PAGE_FLAGS_CHECK_AT_PREP;
>  	}
> -#ifdef CONFIG_MEMCG
> -	if (unlikely(page->mem_cgroup))
> -		bad_reason = "page still charged to cgroup";
> -#endif
>  	bad_page(page, bad_reason, bad_flags);
>  }
>  

I think this is compounding a previous problem in these functions: these 
are all "if" clauses, not "else if" clauses so they are presumably ordered 
based on least significant to most significant (we only see the last 
bad_reason that we find).  For the page->mem_cgroup check, this leaves 
bad_flags set but it doesn't match bad_reason.

Could you instead fix the problem with these functions so that we actually 
list *all* the problems with the page rather than only the last 
conditional that is true?


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad()
  2020-01-19 13:14 ` [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad() Wei Yang
@ 2020-01-19 22:07     ` David Rientjes
  0 siblings, 0 replies; 13+ messages in thread
From: David Rientjes @ 2020-01-19 22:07 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, linux-mm, linux-kernel

On Sun, 19 Jan 2020, Wei Yang wrote:

> free_pages_check_bad() is the counterpart of check_new_page_bad(), while
> their naming convention is a little different.
> 
> Use verb at first and singular form.
> 

I think if you agree with the suggestion in patch 1/4 to fix the issue 
with bad page reporting that it would likely be better to fold patches 2 
and 3 into that change.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad()
@ 2020-01-19 22:07     ` David Rientjes
  0 siblings, 0 replies; 13+ messages in thread
From: David Rientjes @ 2020-01-19 22:07 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, linux-mm, linux-kernel

On Sun, 19 Jan 2020, Wei Yang wrote:

> free_pages_check_bad() is the counterpart of check_new_page_bad(), while
> their naming convention is a little different.
> 
> Use verb at first and singular form.
> 

I think if you agree with the suggestion in patch 1/4 to fix the issue 
with bad page reporting that it would likely be better to fold patches 2 
and 3 into that change.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison
  2020-01-19 13:14 ` [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison Wei Yang
@ 2020-01-19 22:07     ` David Rientjes
  0 siblings, 0 replies; 13+ messages in thread
From: David Rientjes @ 2020-01-19 22:07 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, linux-mm, linux-kernel

On Sun, 19 Jan 2020, Wei Yang wrote:

> Since function returns directly, bad_[reason|flags] is not used any
> where.
> 
> This is a following cleanup for commit e570f56cccd21 ("mm:
> check_new_page_bad() directly returns in __PG_HWPOISON case")
> 
> Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>

Acked-by: David Rientjes <rientjes@google.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison
@ 2020-01-19 22:07     ` David Rientjes
  0 siblings, 0 replies; 13+ messages in thread
From: David Rientjes @ 2020-01-19 22:07 UTC (permalink / raw)
  To: Wei Yang; +Cc: akpm, linux-mm, linux-kernel

On Sun, 19 Jan 2020, Wei Yang wrote:

> Since function returns directly, bad_[reason|flags] is not used any
> where.
> 
> This is a following cleanup for commit e570f56cccd21 ("mm:
> check_new_page_bad() directly returns in __PG_HWPOISON case")
> 
> Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>

Acked-by: David Rientjes <rientjes@google.com>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/4] mm/page_alloc.c: extract commom part to check page
  2020-01-19 22:06     ` David Rientjes
  (?)
@ 2020-01-20  0:33     ` Wei Yang
  -1 siblings, 0 replies; 13+ messages in thread
From: Wei Yang @ 2020-01-20  0:33 UTC (permalink / raw)
  To: David Rientjes; +Cc: Wei Yang, akpm, linux-mm, linux-kernel

On Sun, Jan 19, 2020 at 02:06:18PM -0800, David Rientjes wrote:
>On Sun, 19 Jan 2020, Wei Yang wrote:
>
>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
>> index d047bf7d8fd4..8cd06729169f 100644
>> --- a/mm/page_alloc.c
>> +++ b/mm/page_alloc.c
>> @@ -1025,13 +1025,9 @@ static inline bool page_expected_state(struct page *page,
>>  	return true;
>>  }
>>  
>> -static void free_pages_check_bad(struct page *page)
>> +static inline const char *__check_page(struct page *page)
>>  {
>> -	const char *bad_reason;
>> -	unsigned long bad_flags;
>> -
>> -	bad_reason = NULL;
>> -	bad_flags = 0;
>> +	const char *bad_reason = NULL;
>>  
>>  	if (unlikely(atomic_read(&page->_mapcount) != -1))
>>  		bad_reason = "nonzero mapcount";
>> @@ -1039,14 +1035,23 @@ static void free_pages_check_bad(struct page *page)
>>  		bad_reason = "non-NULL mapping";
>>  	if (unlikely(page_ref_count(page) != 0))
>>  		bad_reason = "nonzero _refcount";
>> -	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
>> -		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
>> -		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
>> -	}
>>  #ifdef CONFIG_MEMCG
>>  	if (unlikely(page->mem_cgroup))
>>  		bad_reason = "page still charged to cgroup";
>>  #endif
>> +	return bad_reason;
>> +}
>> +
>> +static void free_pages_check_bad(struct page *page)
>> +{
>> +	const char *bad_reason = NULL;
>> +	unsigned long bad_flags = 0;
>> +
>> +	bad_reason = __check_page(page);
>> +	if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) {
>> +		bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set";
>> +		bad_flags = PAGE_FLAGS_CHECK_AT_FREE;
>> +	}
>>  	bad_page(page, bad_reason, bad_flags);
>>  }
>>  
>> @@ -2044,12 +2049,7 @@ static void check_new_page_bad(struct page *page)
>>  	const char *bad_reason = NULL;
>>  	unsigned long bad_flags = 0;
>>  
>> -	if (unlikely(atomic_read(&page->_mapcount) != -1))
>> -		bad_reason = "nonzero mapcount";
>> -	if (unlikely(page->mapping != NULL))
>> -		bad_reason = "non-NULL mapping";
>> -	if (unlikely(page_ref_count(page) != 0))
>> -		bad_reason = "nonzero _refcount";
>> +	bad_reason = __check_page(page);
>>  	if (unlikely(page->flags & __PG_HWPOISON)) {
>>  		bad_reason = "HWPoisoned (hardware-corrupted)";
>>  		bad_flags = __PG_HWPOISON;
>> @@ -2061,10 +2061,6 @@ static void check_new_page_bad(struct page *page)
>>  		bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set";
>>  		bad_flags = PAGE_FLAGS_CHECK_AT_PREP;
>>  	}
>> -#ifdef CONFIG_MEMCG
>> -	if (unlikely(page->mem_cgroup))
>> -		bad_reason = "page still charged to cgroup";
>> -#endif
>>  	bad_page(page, bad_reason, bad_flags);
>>  }
>>  
>
>I think this is compounding a previous problem in these functions: these 
>are all "if" clauses, not "else if" clauses so they are presumably ordered 
>based on least significant to most significant (we only see the last 
>bad_reason that we find).  For the page->mem_cgroup check, this leaves 
>bad_flags set but it doesn't match bad_reason.
>

I have thought about this. And curious about the order of those reasons.

>Could you instead fix the problem with these functions so that we actually 
>list *all* the problems with the page rather than only the last 
>conditional that is true?

Sure, thanks for the suggestion.

-- 
Wei Yang
Help you, Help me

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad()
  2020-01-19 22:07     ` David Rientjes
  (?)
@ 2020-01-20  0:36     ` Wei Yang
  -1 siblings, 0 replies; 13+ messages in thread
From: Wei Yang @ 2020-01-20  0:36 UTC (permalink / raw)
  To: David Rientjes; +Cc: Wei Yang, akpm, linux-mm, linux-kernel

On Sun, Jan 19, 2020 at 02:07:04PM -0800, David Rientjes wrote:
>On Sun, 19 Jan 2020, Wei Yang wrote:
>
>> free_pages_check_bad() is the counterpart of check_new_page_bad(), while
>> their naming convention is a little different.
>> 
>> Use verb at first and singular form.
>> 
>
>I think if you agree with the suggestion in patch 1/4 to fix the issue 
>with bad page reporting that it would likely be better to fold patches 2 
>and 3 into that change.

I am ok with this, while would it be confusing for review?

-- 
Wei Yang
Help you, Help me

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-01-20  0:36 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-19 13:14 [PATCH 0/4] mm/page_alloc.c: cleanup on check page Wei Yang
2020-01-19 13:14 ` [PATCH 1/4] mm/page_alloc.c: extract commom part to " Wei Yang
2020-01-19 22:06   ` David Rientjes
2020-01-19 22:06     ` David Rientjes
2020-01-20  0:33     ` Wei Yang
2020-01-19 13:14 ` [PATCH 2/4] mm/page_alloc.c: rename free_pages_check_bad() to check_free_page_bad() Wei Yang
2020-01-19 22:07   ` David Rientjes
2020-01-19 22:07     ` David Rientjes
2020-01-20  0:36     ` Wei Yang
2020-01-19 13:14 ` [PATCH 3/4] mm/page_alloc.c: rename free_pages_check() to check_free_page() Wei Yang
2020-01-19 13:14 ` [PATCH 4/4] mm/page_alloc.c: bad_[reason|flags] is not necessary when PageHWPoison Wei Yang
2020-01-19 22:07   ` David Rientjes
2020-01-19 22:07     ` David Rientjes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.