@@ -30,10 +30,12 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_
/*
* We assume the caller intended to SET migrate type to isolate.
* If it is already set, then someone else must have raced and
- * set it before us. Return -EBUSY
+ * set it before us. Return -EAGAIN
*/
- if (is_migrate_isolate_page(page))
+ if (is_migrate_isolate_page(page)) {
+ ret = -EAGAIN;
goto out;
+ }
pfn = page_to_pfn(page);
arg.start_pfn = pfn;
@@ -188,6 +190,7 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
unsigned long pfn;
unsigned long undo_pfn;
struct page *page;
+ int ret = -EBUSY;
BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages));
@@ -196,10 +199,13 @@ 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 &&
- set_migratetype_isolate(page, migratetype, flags)) {
- undo_pfn = pfn;
- goto undo;
+ if (page) {
+ ret = set_migratetype_isolate(page, migratetype,
+ flags);
+ if (ret) {
+ undo_pfn = pfn;
+ goto undo;
+ }
}
}
return 0;
@@ -213,7 +219,7 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
unset_migratetype_isolate(page, migratetype);
}
- return -EBUSY;
+ return ret;
}
/*
If the page isolation failed because of racing the setup of the pages migrate type, it is very likely that a further attempt will succeed. In this case, instead of -EBUSY, return -EAGAIN, to let callers handle this condition properly. Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com> --- mm/page_isolation.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)