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:
parent
498aefbc69
commit
9cbe4954c6
17
mm/gup.c
17
mm/gup.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user