gup: use folios for gup_devmap

Use try_grab_folio() instead of try_grab_page() so we get the folio back
that we calculated, and then use folio_set_referenced() instead of
SetPageReferenced().  Correspondingly, use gup_put_folio() to put any
unneeded references.

Link: https://lkml.kernel.org/r/20240424191914.361554-6-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Matthew Wilcox (Oracle) 2024-04-24 20:19:10 +01:00 committed by Andrew Morton
parent 498aefbc69
commit 9cbe4954c6

View File

@ -2877,13 +2877,10 @@ static void __maybe_unused gup_fast_undo_dev_pagemap(int *nr, int nr_start,
unsigned int flags, struct page **pages) unsigned int flags, struct page **pages)
{ {
while ((*nr) - nr_start) { while ((*nr) - nr_start) {
struct page *page = pages[--(*nr)]; struct folio *folio = page_folio(pages[--(*nr)]);
ClearPageReferenced(page); folio_clear_referenced(folio);
if (flags & FOLL_PIN) gup_put_folio(folio, 1, flags);
unpin_user_page(page);
else
put_page(page);
} }
} }
@ -3024,6 +3021,7 @@ static int gup_fast_devmap_leaf(unsigned long pfn, unsigned long addr,
struct dev_pagemap *pgmap = NULL; struct dev_pagemap *pgmap = NULL;
do { do {
struct folio *folio;
struct page *page = pfn_to_page(pfn); struct page *page = pfn_to_page(pfn);
pgmap = get_dev_pagemap(pfn, pgmap); pgmap = get_dev_pagemap(pfn, pgmap);
@ -3037,12 +3035,13 @@ static int gup_fast_devmap_leaf(unsigned long pfn, unsigned long addr,
break; break;
} }
SetPageReferenced(page); folio = try_grab_folio(page, 1, flags);
pages[*nr] = page; if (!folio) {
if (unlikely(try_grab_page(page, flags))) {
gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages); gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
break; break;
} }
folio_set_referenced(folio);
pages[*nr] = page;
(*nr)++; (*nr)++;
pfn++; pfn++;
} while (addr += PAGE_SIZE, addr != end); } while (addr += PAGE_SIZE, addr != end);