aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Tatashin <[email protected]>2021-05-04 18:38:46 -0700
committerLinus Torvalds <[email protected]>2021-05-05 11:27:26 -0700
commitf0f4463837da17a89d965dcbe4e411629dbcf308 (patch)
tree03e6eb3f8d8ac8a3eef6cb91cf8e5f8646229321
parent83c02c23d0747a7bdcd71f99a538aacec94b146c (diff)
mm/gup: return an error on migration failure
When migration failure occurs, we still pin pages, which means that we may pin CMA movable pages which should never be the case. Instead return an error without pinning pages when migration failure happens. No need to retry migrating, because migrate_pages() already retries 10 times. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Pavel Tatashin <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Cc: Dan Williams <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: David Rientjes <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Ira Weiny <[email protected]> Cc: James Morris <[email protected]> Cc: Jason Gunthorpe <[email protected]> Cc: John Hubbard <[email protected]> Cc: Joonsoo Kim <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Oscar Salvador <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sasha Levin <[email protected]> Cc: Steven Rostedt (VMware) <[email protected]> Cc: Tyler Hicks <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r--mm/gup.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/mm/gup.c b/mm/gup.c
index 16015718c0df..da08c582c216 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1610,7 +1610,6 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
{
unsigned long i;
bool drain_allow = true;
- bool migrate_allow = true;
LIST_HEAD(cma_page_list);
long ret = nr_pages;
struct page *prev_head, *head;
@@ -1661,17 +1660,15 @@ check_again:
for (i = 0; i < nr_pages; i++)
put_page(pages[i]);
- if (migrate_pages(&cma_page_list, alloc_migration_target, NULL,
- (unsigned long)&mtc, MIGRATE_SYNC, MR_CONTIG_RANGE)) {
- /*
- * some of the pages failed migration. Do get_user_pages
- * without migration.
- */
- migrate_allow = false;
-
+ ret = migrate_pages(&cma_page_list, alloc_migration_target,
+ NULL, (unsigned long)&mtc, MIGRATE_SYNC,
+ MR_CONTIG_RANGE);
+ if (ret) {
if (!list_empty(&cma_page_list))
putback_movable_pages(&cma_page_list);
+ return ret > 0 ? -ENOMEM : ret;
}
+
/*
* We did migrate all the pages, Try to get the page references
* again migrating any new CMA pages which we failed to isolate
@@ -1681,7 +1678,7 @@ check_again:
pages, vmas, NULL,
gup_flags);
- if ((ret > 0) && migrate_allow) {
+ if (ret > 0) {
nr_pages = ret;
drain_allow = true;
goto check_again;