]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mm: do not use page_count() without a page pin
authorMinchan Kim <minchan@kernel.org>
Sat, 21 Jul 2012 00:54:10 +0000 (10:54 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 25 Jul 2012 03:02:29 +0000 (13:02 +1000)
d179e84ba ("mm: vmscan: do not use page_count without a page pin") fixed
this problem in vmscan.c but same problem is in __count_immobile_pages().

I copy and paste d179e84ba's contents for description.

"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."

Signed-off-by: Minchan Kim <minchan@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Michal Hocko <mhocko@suse.cz>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Wanpeng Li <liwp.linux@gmail.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/page_alloc.c

index 441d77c3e810db0c8b938960a1c6e6322fa7fd04..710add6f17b3b9ed4f1e1dd90e8b4c7836ded16f 100644 (file)
@@ -5499,11 +5499,18 @@ __count_immobile_pages(struct zone *zone, struct page *page, int count)
                        continue;
 
                page = pfn_to_page(check);
-               if (!page_count(page)) {
+               /*
+                * We can't use page_count without pin a page
+                * because another CPU can free compound page.
+                * This check already skips compound tails of THP
+                * because their page->_count is zero at all time.
+                */
+               if (!atomic_read(&page->_count)) {
                        if (PageBuddy(page))
                                iter += (1 << page_order(page)) - 1;
                        continue;
                }
+
                if (!PageLRU(page))
                        found++;
                /*