diff options
Diffstat (limited to 'mm/page_isolation.c')
| -rw-r--r-- | mm/page_isolation.c | 29 | 
1 files changed, 10 insertions, 19 deletions
| diff --git a/mm/page_isolation.c b/mm/page_isolation.c index a95c2c6562d0..f67c4c70f17f 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -94,8 +94,13 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)  			buddy = page + (buddy_pfn - pfn);  			if (!is_migrate_isolate_page(buddy)) { -				__isolate_free_page(page, order); -				isolated_page = true; +				isolated_page = !!__isolate_free_page(page, order); +				/* +				 * Isolating a free page in an isolated pageblock +				 * is expected to always work as watermarks don't +				 * apply here. +				 */ +				VM_WARN_ON(!isolated_page);  			}  		}  	} @@ -183,7 +188,6 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,  			     unsigned migratetype, int flags)  {  	unsigned long pfn; -	unsigned long undo_pfn;  	struct page *page;  	BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages)); @@ -193,25 +197,12 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,  	     pfn < end_pfn;  	     pfn += pageblock_nr_pages) {  		page = __first_valid_page(pfn, pageblock_nr_pages); -		if (page) { -			if (set_migratetype_isolate(page, migratetype, flags)) { -				undo_pfn = pfn; -				goto undo; -			} +		if (page && set_migratetype_isolate(page, migratetype, flags)) { +			undo_isolate_page_range(start_pfn, pfn, migratetype); +			return -EBUSY;  		}  	}  	return 0; -undo: -	for (pfn = start_pfn; -	     pfn < undo_pfn; -	     pfn += pageblock_nr_pages) { -		struct page *page = pfn_to_online_page(pfn); -		if (!page) -			continue; -		unset_migratetype_isolate(page, migratetype); -	} - -	return -EBUSY;  }  /* |