Skip to content

Commit

Permalink
mm: page_alloc: clear PG_locked before checking flags on free
Browse files Browse the repository at this point in the history
da456f1 "page allocator: do not disable interrupts in free_page_mlock()" moved
the PG_mlocked clearing after the flag sanity checking which makes mlocked
pages always trigger 'bad page'.  Fix this by clearing the bit up front.

Reported--and-debugged-by: Peter Chubb <[email protected]>
Signed-off-by: Johannes Weiner <[email protected]>
Acked-by: Mel Gorman <[email protected]>
Tested-by: Maxim Levitsky <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
hnaz authored and torvalds committed Jun 20, 2009
1 parent 9063c61 commit c277331
Showing 1 changed file with 4 additions and 5 deletions.
9 changes: 4 additions & 5 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,6 @@ static inline void __free_one_page(struct page *page,
*/
static inline void free_page_mlock(struct page *page)
{
__ClearPageMlocked(page);
__dec_zone_page_state(page, NR_MLOCK);
__count_vm_event(UNEVICTABLE_MLOCKFREED);
}
Expand Down Expand Up @@ -558,7 +557,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
unsigned long flags;
int i;
int bad = 0;
int clearMlocked = PageMlocked(page);
int wasMlocked = TestClearPageMlocked(page);

kmemcheck_free_shadow(page, order);

Expand All @@ -576,7 +575,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
kernel_map_pages(page, 1 << order, 0);

local_irq_save(flags);
if (unlikely(clearMlocked))
if (unlikely(wasMlocked))
free_page_mlock(page);
__count_vm_events(PGFREE, 1 << order);
free_one_page(page_zone(page), page, order,
Expand Down Expand Up @@ -1022,7 +1021,7 @@ static void free_hot_cold_page(struct page *page, int cold)
struct zone *zone = page_zone(page);
struct per_cpu_pages *pcp;
unsigned long flags;
int clearMlocked = PageMlocked(page);
int wasMlocked = TestClearPageMlocked(page);

kmemcheck_free_shadow(page, 0);

Expand All @@ -1041,7 +1040,7 @@ static void free_hot_cold_page(struct page *page, int cold)
pcp = &zone_pcp(zone, get_cpu())->pcp;
set_page_private(page, get_pageblock_migratetype(page));
local_irq_save(flags);
if (unlikely(clearMlocked))
if (unlikely(wasMlocked))
free_page_mlock(page);
__count_vm_event(PGFREE);

Expand Down

0 comments on commit c277331

Please sign in to comment.