[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210517140310.133885570@linuxfoundation.org>
Date: Mon, 17 May 2021 16:01:29 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Pavel Tatashin <pasha.tatashin@...een.com>,
Jason Gunthorpe <jgg@...dia.com>,
Dan Williams <dan.j.williams@...el.com>,
David Hildenbrand <david@...hat.com>,
David Rientjes <rientjes@...gle.com>,
Ingo Molnar <mingo@...hat.com>,
Ira Weiny <ira.weiny@...el.com>,
James Morris <jmorris@...ei.org>,
Jason Gunthorpe <jgg@...pe.ca>,
John Hubbard <jhubbard@...dia.com>,
Joonsoo Kim <iamjoonsoo.kim@....com>,
Matthew Wilcox <willy@...radead.org>,
Mel Gorman <mgorman@...e.de>, Michal Hocko <mhocko@...nel.org>,
Michal Hocko <mhocko@...e.com>,
Mike Kravetz <mike.kravetz@...cle.com>,
Oscar Salvador <osalvador@...e.de>,
Peter Zijlstra <peterz@...radead.org>,
Sasha Levin <sashal@...nel.org>,
"Steven Rostedt (VMware)" <rostedt@...dmis.org>,
Tyler Hicks <tyhicks@...ux.microsoft.com>,
Vlastimil Babka <vbabka@...e.cz>,
Andrew Morton <akpm@...ux-foundation.org>,
Linus Torvalds <torvalds@...ux-foundation.org>
Subject: [PATCH 5.12 223/363] mm/gup: check for isolation errors
From: Pavel Tatashin <pasha.tatashin@...een.com>
[ Upstream commit 6e7f34ebb8d25d71ce7f4580ba3cbfc10b895580 ]
It is still possible that we pin movable CMA pages if there are
isolation errors and cma_page_list stays empty when we check again.
Check for isolation errors, and return success only when there are no
isolation errors, and cma_page_list is empty after checking.
Because isolation errors are transient, we retry indefinitely.
Link: https://lkml.kernel.org/r/20210215161349.246722-5-pasha.tatashin@soleen.com
Fixes: 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region")
Signed-off-by: Pavel Tatashin <pasha.tatashin@...een.com>
Reviewed-by: Jason Gunthorpe <jgg@...dia.com>
Cc: Dan Williams <dan.j.williams@...el.com>
Cc: David Hildenbrand <david@...hat.com>
Cc: David Rientjes <rientjes@...gle.com>
Cc: Ingo Molnar <mingo@...hat.com>
Cc: Ira Weiny <ira.weiny@...el.com>
Cc: James Morris <jmorris@...ei.org>
Cc: Jason Gunthorpe <jgg@...pe.ca>
Cc: John Hubbard <jhubbard@...dia.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@....com>
Cc: Matthew Wilcox <willy@...radead.org>
Cc: Mel Gorman <mgorman@...e.de>
Cc: Michal Hocko <mhocko@...nel.org>
Cc: Michal Hocko <mhocko@...e.com>
Cc: Mike Kravetz <mike.kravetz@...cle.com>
Cc: Oscar Salvador <osalvador@...e.de>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Sasha Levin <sashal@...nel.org>
Cc: Steven Rostedt (VMware) <rostedt@...dmis.org>
Cc: Tyler Hicks <tyhicks@...ux.microsoft.com>
Cc: Vlastimil Babka <vbabka@...e.cz>
Signed-off-by: Andrew Morton <akpm@...ux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@...ux-foundation.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
mm/gup.c | 60 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 34 insertions(+), 26 deletions(-)
diff --git a/mm/gup.c b/mm/gup.c
index 2b48c65e27cc..333f5dfd8942 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1551,8 +1551,8 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
struct vm_area_struct **vmas,
unsigned int gup_flags)
{
- unsigned long i;
- bool drain_allow = true;
+ unsigned long i, isolation_error_count;
+ bool drain_allow;
LIST_HEAD(cma_page_list);
long ret = nr_pages;
struct page *prev_head, *head;
@@ -1563,6 +1563,8 @@ static long check_and_migrate_cma_pages(struct mm_struct *mm,
check_again:
prev_head = NULL;
+ isolation_error_count = 0;
+ drain_allow = true;
for (i = 0; i < nr_pages; i++) {
head = compound_head(pages[i]);
if (head == prev_head)
@@ -1574,25 +1576,35 @@ check_again:
* of the CMA zone if possible.
*/
if (is_migrate_cma_page(head)) {
- if (PageHuge(head))
- isolate_huge_page(head, &cma_page_list);
- else {
+ if (PageHuge(head)) {
+ if (!isolate_huge_page(head, &cma_page_list))
+ isolation_error_count++;
+ } else {
if (!PageLRU(head) && drain_allow) {
lru_add_drain_all();
drain_allow = false;
}
- if (!isolate_lru_page(head)) {
- list_add_tail(&head->lru, &cma_page_list);
- mod_node_page_state(page_pgdat(head),
- NR_ISOLATED_ANON +
- page_is_file_lru(head),
- thp_nr_pages(head));
+ if (isolate_lru_page(head)) {
+ isolation_error_count++;
+ continue;
}
+ list_add_tail(&head->lru, &cma_page_list);
+ mod_node_page_state(page_pgdat(head),
+ NR_ISOLATED_ANON +
+ page_is_file_lru(head),
+ thp_nr_pages(head));
}
}
}
+ /*
+ * If list is empty, and no isolation errors, means that all pages are
+ * in the correct zone.
+ */
+ if (list_empty(&cma_page_list) && !isolation_error_count)
+ return ret;
+
if (!list_empty(&cma_page_list)) {
/*
* drop the above get_user_pages reference.
@@ -1612,23 +1624,19 @@ check_again:
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
- * earlier.
- */
- ret = __get_user_pages_locked(mm, start, nr_pages,
- pages, vmas, NULL,
- gup_flags);
-
- if (ret > 0) {
- nr_pages = ret;
- drain_allow = true;
- goto check_again;
- }
+ /* We unpinned pages before migration, pin them again */
+ ret = __get_user_pages_locked(mm, start, nr_pages, pages, vmas,
+ NULL, gup_flags);
+ if (ret <= 0)
+ return ret;
+ nr_pages = ret;
}
- return ret;
+ /*
+ * check again because pages were unpinned, and we also might have
+ * had isolation errors and need more pages to migrate.
+ */
+ goto check_again;
}
#else
static long check_and_migrate_cma_pages(struct mm_struct *mm,
--
2.30.2
Powered by blists - more mailing lists