mm: vmscan: do not use page_count without a page pin

It is unsafe to run page_count during the physical pfn scan because
compound_head could trip on a dangling pointer when reading
page->first_page if the compound page is being freed by another CPU.

[mgorman@suse.de: split out patch]
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Reviewed-by: Minchan Kim <minchan.kim@gmail.com>

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Andrea Arcangeli 2011-06-15 15:08:51 -07:00 committed by Linus Torvalds
parent 7454f4ba40
commit d179e84ba5

View File

@ -1124,8 +1124,20 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
nr_lumpy_dirty++;
scan++;
} else {
/* the page is freed already. */
if (!page_count(cursor_page))
/*
* Check if the page is freed already.
*
* We can't use page_count() as that
* requires compound_head and we don't
* have a pin on the page here. If a
* page is tail, we may or may not
* have isolated the head, so assume
* it's not free, it'd be tricky to
* track the head status without a
* page pin.
*/
if (!PageTail(cursor_page) &&
!atomic_read(&cursor_page->_count))
continue;
break;
}