Re: [PATCH 04/10] mm/page_alloc: carefully free the page on isolate pageblock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/04/2014 09:57 AM, Joonsoo Kim wrote:
We got migratetype without holding the lock so it could be
racy. If some pages go on the isolate migratetype buddy list
by this race, we can't allocate this page anymore until next
isolation attempt on this pageblock. Below is possible
scenario of this race.

pageblock 1 is isolate migratetype.

CPU1					CPU2
- get_pfnblock_migratetype(pageblock 1),
so MIGRATE_ISOLATE is returned
- call free_one_page() with MIGRATE_ISOLATE
					- grab the zone lock
					- unisolate pageblock 1
					- release the zone lock
- grab the zone lock
- call __free_one_page() with MIGRATE_ISOLATE
- free page go into isolate buddy list
and we can't use it anymore

To prevent this possibility, re-check migratetype with holding the lock.

This could be also solved similarly to the other races, if during unisolation, CPU2 sent a drain_all_pages() IPI and only then used move_freepages_block(). Again, get_pfnblock_migratetype() on CPU1 would need to be moved under disabled irq's.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@xxxxxxx>
---
  mm/page_alloc.c |   11 +++++++++++
  1 file changed, 11 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 99c05f7..d8feedc 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -743,6 +743,17 @@ static void free_one_page(struct zone *zone,
  	spin_lock(&zone->lock);
  	zone->pages_scanned = 0;

+	if (unlikely(is_migrate_isolate(migratetype))) {
+		/*
+		 * We got migratetype without holding the lock so it could be
+		 * racy. If some pages go on the isolate migratetype buddy list
+		 * by this race, we can't allocate this page anymore until next
+		 * isolation attempt on this pageblock. To prevent this
+		 * possibility, re-check migratetype with holding the lock.
+		 */
+		migratetype = get_pfnblock_migratetype(page, pfn);
+	}
+
  	__free_one_page(page, pfn, zone, order, migratetype);
  	if (!is_migrate_isolate(migratetype))
  		__mod_zone_freepage_state(zone, 1 << order, migratetype);


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxx.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]