Skip to content

Commit 1aaf8c1

Browse files
Zhaoyang Huangakpm00
authored andcommitted
mm: gup: fix infinite loop within __get_longterm_locked
We can run into an infinite loop in __get_longterm_locked() when collect_longterm_unpinnable_folios() finds only folios that are isolated from the LRU or were never added to the LRU. This can happen when all folios to be pinned are never added to the LRU, for example when vm_ops->fault allocated pages using cma_alloc() and never added them to the LRU. Fix it by simply taking a look at the list in the single caller, to see if anything was added. [zhaoyang.huang@unisoc.com: move definition of local] Link: https://lkml.kernel.org/r/20250122012604.3654667-1-zhaoyang.huang@unisoc.com Link: https://lkml.kernel.org/r/20250121020159.3636477-1-zhaoyang.huang@unisoc.com Fixes: 67e139b ("mm/gup.c: refactor check_and_migrate_movable_pages()") Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com> Reviewed-by: John Hubbard <jhubbard@nvidia.com> Reviewed-by: David Hildenbrand <david@redhat.com> Suggested-by: David Hildenbrand <david@redhat.com> Acked-by: David Hildenbrand <david@redhat.com> Cc: Aijun Sun <aijun.sun@unisoc.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 498c48c commit 1aaf8c1

File tree

1 file changed

+4
-10
lines changed

1 file changed

+4
-10
lines changed

mm/gup.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,13 +2320,13 @@ static void pofs_unpin(struct pages_or_folios *pofs)
23202320
/*
23212321
* Returns the number of collected folios. Return value is always >= 0.
23222322
*/
2323-
static unsigned long collect_longterm_unpinnable_folios(
2323+
static void collect_longterm_unpinnable_folios(
23242324
struct list_head *movable_folio_list,
23252325
struct pages_or_folios *pofs)
23262326
{
2327-
unsigned long i, collected = 0;
23282327
struct folio *prev_folio = NULL;
23292328
bool drain_allow = true;
2329+
unsigned long i;
23302330

23312331
for (i = 0; i < pofs->nr_entries; i++) {
23322332
struct folio *folio = pofs_get_folio(pofs, i);
@@ -2338,8 +2338,6 @@ static unsigned long collect_longterm_unpinnable_folios(
23382338
if (folio_is_longterm_pinnable(folio))
23392339
continue;
23402340

2341-
collected++;
2342-
23432341
if (folio_is_device_coherent(folio))
23442342
continue;
23452343

@@ -2361,8 +2359,6 @@ static unsigned long collect_longterm_unpinnable_folios(
23612359
NR_ISOLATED_ANON + folio_is_file_lru(folio),
23622360
folio_nr_pages(folio));
23632361
}
2364-
2365-
return collected;
23662362
}
23672363

23682364
/*
@@ -2439,11 +2435,9 @@ static long
24392435
check_and_migrate_movable_pages_or_folios(struct pages_or_folios *pofs)
24402436
{
24412437
LIST_HEAD(movable_folio_list);
2442-
unsigned long collected;
24432438

2444-
collected = collect_longterm_unpinnable_folios(&movable_folio_list,
2445-
pofs);
2446-
if (!collected)
2439+
collect_longterm_unpinnable_folios(&movable_folio_list, pofs);
2440+
if (list_empty(&movable_folio_list))
24472441
return 0;
24482442

24492443
return migrate_longterm_unpinnable_folios(&movable_folio_list, pofs);

0 commit comments

Comments
 (0)