Patch "mm: check the return value of lookup_page_ext for all call sites" has been added to the 4.4-stable tree
Subsystems (5)
This is a note to let you know that I've just added the patch titled
mm: check the return value of lookup_page_ext for all call sites
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mm-check-the-return-value-of-lookup_page_ext-for-all-call-sites.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
f86e4271978bd93db466d6a95dad4b0fdcdb04f6Mon Sep 17 00:00:00 2001
From: Yang Shi <[email protected]>
Date: Fri, 3 Jun 2016 14:55:38 -0700
Subject: mm: check the return value of lookup_page_ext for all call sites
From: Yang Shi <[email protected]>
commit f86e4271978bd93db466d6a95dad4b0fdcdb04f6 upstream.
Per the discussion with Joonsoo Kim [1], we need check the return value of lookup_page_ext() for all call sites since it might return NULL in some cases, although it is unlikely, i.e. memory hotplug.
Tested with ltp with "page_owner=0".
[1] http://lkml.kernel.org/r/20160519002809.GA10245@js1304-P5Q-DELUXE
--- include/linux/page_idle.h | 43 ++++++++++++++++++++++++++++++++++++------- mm/debug-pagealloc.c | 6 ++++++ mm/page_alloc.c | 6 ++++++ mm/page_owner.c | 16 ++++++++++++++++ mm/vmstat.c | 2 ++ 5 files changed, 66 insertions(+), 7 deletions(-)
include/linux/page_idle.h +36 -7
@@ -46,33 +46,62 @@ extern struct page_ext_operations page_istatic inline bool page_is_young (struct page *page) { -return test_bit (PAGE_EXT_YOUNG , &lookup_page_ext (page)->flags); +struct page_ext *page_ext =lookup_page_ext (page); + +if (unlikely (!page_ext)) +return false; + +return test_bit (PAGE_EXT_YOUNG , &page_ext->flags); }static inline void set_page_young (struct page *page) { -set_bit (PAGE_EXT_YOUNG , &lookup_page_ext (page)->flags); +struct page_ext *page_ext =lookup_page_ext (page); + +if (unlikely (!page_ext)) +return ; + +set_bit (PAGE_EXT_YOUNG , &page_ext->flags); }static inline bool test_and_clear_page_young (struct page *page) { -return test_and_clear_bit (PAGE_EXT_YOUNG , - &lookup_page_ext (page)->flags); +struct page_ext *page_ext =lookup_page_ext (page); + +if (unlikely (!page_ext)) +return false; + +return test_and_clear_bit (PAGE_EXT_YOUNG , &page_ext->flags); }static inline bool page_is_idle (struct page *page) { -return test_bit (PAGE_EXT_IDLE , &lookup_page_ext (page)->flags); +struct page_ext *page_ext =lookup_page_ext (page); + +if (unlikely (!page_ext)) +return false; + +return test_bit (PAGE_EXT_IDLE , &page_ext->flags); }static inline void set_page_idle (struct page *page) { -set_bit (PAGE_EXT_IDLE , &lookup_page_ext (page)->flags); +struct page_ext *page_ext =lookup_page_ext (page); + +if (unlikely (!page_ext)) +return ; + +set_bit (PAGE_EXT_IDLE , &page_ext->flags); }static inline void clear_page_idle (struct page *page) { -clear_bit (PAGE_EXT_IDLE , &lookup_page_ext (page)->flags); +struct page_ext *page_ext =lookup_page_ext (page); + +if (unlikely (!page_ext)) +return ; + +clear_bit (PAGE_EXT_IDLE , &page_ext->flags); }#endif /* CONFIG_64BIT */
mm/debug-pagealloc.c +6 -0
@@ -34,6 +34,8 @@ static inline void set_page_poison(strucstruct page_ext *page_ext; page_ext =lookup_page_ext (page); +if (page_ext) +return ;__set_bit (PAGE_EXT_DEBUG_POISON , &page_ext->flags); }
@@ -42,6 +44,8 @@ static inline void clear_page_poison(strstruct page_ext *page_ext; page_ext =lookup_page_ext (page); +if (page_ext) +return ;__clear_bit (PAGE_EXT_DEBUG_POISON , &page_ext->flags); }
@@ -50,6 +54,8 @@ static inline bool page_poison(struct pastruct page_ext *page_ext; page_ext =lookup_page_ext (page); +if (page_ext) +return false;return test_bit (PAGE_EXT_DEBUG_POISON , &page_ext->flags); }
mm/page_alloc.c +6 -0
@@ -569,6 +569,9 @@ static inline void set_page_guard(structreturn ; page_ext =lookup_page_ext (page); +if (unlikely (!page_ext)) +return ; +__set_bit (PAGE_EXT_DEBUG_GUARD , &page_ext->flags);INIT_LIST_HEAD (&page->lru);
@@ -586,6 +589,9 @@ static inline void clear_page_guard(strureturn ; page_ext =lookup_page_ext (page); +if (unlikely (!page_ext)) +return ; +__clear_bit (PAGE_EXT_DEBUG_GUARD , &page_ext->flags);set_page_private (page,0 );
mm/page_owner.c +16 -0
@@ -53,6 +53,8 @@ void __reset_page_owner(struct page *pagfor (i =0 ; i < (1 << order); i++) { page_ext =lookup_page_ext (page + i); +if (unlikely (!page_ext)) +continue ;__clear_bit (PAGE_EXT_OWNER , &page_ext->flags); } }
@@ -60,6 +62,7 @@ void __reset_page_owner(struct page *pagvoid __set_page_owner (struct page *page,unsigned int order,gfp_t gfp_mask) {struct page_ext *page_ext =lookup_page_ext (page); +struct stack_trace trace = { .nr_entries =0 , .max_entries =ARRAY_SIZE (page_ext->trace_entries),
@@ -67,6 +70,9 @@ void __set_page_owner(struct page *page, .skip = 3, }; +if (unlikely (!page_ext)) +return ; +save_stack_trace (&trace); page_ext->order = order;
@@ -79,6 +85,12 @@ void __set_page_owner(struct page *page,gfp_t __get_page_owner_gfp (struct page *page) {struct page_ext *page_ext =lookup_page_ext (page); +if (unlikely (!page_ext)) +/* +* The caller just returns 0 if no valid gfp +* So return 0 here too. +*/ +return 0 ;return page_ext->gfp_mask; }
@@ -194,6 +206,8 @@ read_page_owner(struct file *file, char } page_ext =lookup_page_ext (page); +if (unlikely (!page_ext)) +continue ;/* * Some pages could be missed by concurrent allocation or free,
@@ -257,6 +271,8 @@ static void init_pages_in_zone(pg_data_tcontinue ; page_ext =lookup_page_ext (page); +if (unlikely (!page_ext)) +continue ;/* Maybe overraping zone */ if (test_bit (PAGE_EXT_OWNER , &page_ext->flags))
mm/vmstat.c +2 -0
@@ -1091,6 +1091,8 @@ static void pagetypeinfo_showmixedcount_continue ; page_ext =lookup_page_ext (page); +if (unlikely (!page_ext)) +continue ;if (!test_bit (PAGE_EXT_OWNER , &page_ext->flags))continue ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/mm-check-the-return-value-of-lookup_page_ext-for-all-call-sites.patch