From: Yaowei Bai <hidden> Date: 2015-08-25 13:32:05
The major portion of check_new_page() and free_pages_check() are same,
introduce a helper function check_one_page() for simplification.
Change in v2:
- use bad_flags as parameter directly per Michal Hocko
Signed-off-by: Yaowei Bai <redacted>
---
mm/page_alloc.c | 49 ++++++++++++++++++-------------------------------
1 file changed, 18 insertions(+), 31 deletions(-)
@@ -718,9 +717,11 @@ static inline int free_pages_check(struct page *page)bad_reason="non-NULL mapping";if(unlikely(atomic_read(&page->_count)!=0))bad_reason="nonzero _count";-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;+if(unlikely(page->flags&bad_flags)){+if(bad_flags==PAGE_FLAGS_CHECK_AT_PREP)+bad_reason="PAGE_FLAGS_CHECK_AT_PREP flag set";+elseif(bad_flags==PAGE_FLAGS_CHECK_AT_FREE)+bad_reason="PAGE_FLAGS_CHECK_AT_FREE flag set";}#ifdef CONFIG_MEMCGif(unlikely(page->mem_cgroup))
@@ -730,6 +731,17 @@ static inline int free_pages_check(struct page *page)bad_page(page,bad_reason,bad_flags);return1;}+return0;+}++staticinlineintfree_pages_check(structpage*page)+{+intret=0;++ret=check_one_page(page,PAGE_FLAGS_CHECK_AT_FREE);+if(ret)+returnret;+page_cpupid_reset_last(page);if(page->flags&PAGE_FLAGS_CHECK_AT_PREP)page->flags&=~PAGE_FLAGS_CHECK_AT_PREP;
@@ -1287,32 +1299,7 @@ static inline void expand(struct zone *zone, struct page *page,*/staticinlineintcheck_new_page(structpage*page){-constchar*bad_reason=NULL;-unsignedlongbad_flags=0;--if(unlikely(page_mapcount(page)))-bad_reason="nonzero mapcount";-if(unlikely(page->mapping!=NULL))-bad_reason="non-NULL mapping";-if(unlikely(atomic_read(&page->_count)!=0))-bad_reason="nonzero _count";-if(unlikely(page->flags&__PG_HWPOISON)){-bad_reason="HWPoisoned (hardware-corrupted)";-bad_flags=__PG_HWPOISON;-}-if(unlikely(page->flags&PAGE_FLAGS_CHECK_AT_PREP)){-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-if(unlikely(bad_reason)){-bad_page(page,bad_reason,bad_flags);-return1;-}-return0;+returncheck_one_page(page,PAGE_FLAGS_CHECK_AT_PREP);}staticintprep_new_page(structpage*page,unsignedintorder,gfp_tgfp_flags,
--
1.9.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
You have removed this check AFAICS. Now looking at 39ad4f19671d ("mm:
check __PG_HWPOISON separately from PAGE_FLAGS_CHECK_AT_*") I am not
sure it is correct to check it in the free path as it was removed from
the mask by this commit.
- if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_PREP)) {
- 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
- if (unlikely(bad_reason)) {
- bad_page(page, bad_reason, bad_flags);
- return 1;
- }
- return 0;
+ return check_one_page(page, PAGE_FLAGS_CHECK_AT_PREP);
}
static int prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,
--
1.9.1
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
You have removed this check AFAICS. Now looking at 39ad4f19671d ("mm:
I missed that check mistakenly, it should be there.
check __PG_HWPOISON separately from PAGE_FLAGS_CHECK_AT_*") I am not
sure it is correct to check it in the free path as it was removed from
the mask by this commit.
I investigated the commit you mentioned above. AFAICS, that commit assumes
that __PG_HWPOISON check should be performed in the alloc path, while in
the free path it doesn't need to. So there is a bit different in alloc/free
paths.
So Michal, do you think there is any obvious points to refactor these
two functions still? Anyway, appreciate your reviewing.
quoted
- if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_PREP)) {
- 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
- if (unlikely(bad_reason)) {
- bad_page(page, bad_reason, bad_flags);
- return 1;
- }
- return 0;
+ return check_one_page(page, PAGE_FLAGS_CHECK_AT_PREP);
}
static int prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,
--
1.9.1
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
You have removed this check AFAICS. Now looking at 39ad4f19671d ("mm:
check __PG_HWPOISON separately from PAGE_FLAGS_CHECK_AT_*") I am not
sure it is correct to check it in the free path as it was removed from
the mask by this commit.
I just refactored these two function and it looks well, will resend it soon.
quoted
- if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_PREP)) {
- 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
- if (unlikely(bad_reason)) {
- bad_page(page, bad_reason, bad_flags);
- return 1;
- }
- return 0;
+ return check_one_page(page, PAGE_FLAGS_CHECK_AT_PREP);
}
static int prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,
--
1.9.1
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>