On Fri, Aug 27, 2021 at 03:58:13PM +0100, Joao Martins wrote:
quoted hunk ↗ jump to hunk
@@ -2252,16 +2265,25 @@ static int __gup_device_huge(unsigned long pfn, unsigned long addr,
ret = 0;
break;
}
- SetPageReferenced(page);
- pages[*nr] = page;
- if (unlikely(!try_grab_page(page, flags))) {
- undo_dev_pagemap(nr, nr_start, flags, pages);
+
+ head = compound_head(page);
+ /* @end is assumed to be limited at most one compound page */
+ if (PageHead(head))
+ next = end;
+ refs = record_subpages(page, addr, next, pages + *nr);
+
+ SetPageReferenced(head);
+ if (unlikely(!try_grab_compound_head(head, refs, flags))) {
I was thinking about this some more, and this ordering doesn't seem
like a good idea. We shouldn't be looking at any part of the struct
page without holding the refcount, certainly not the compound_head()
The only optimization that might work here is to grab the head, then
compute the extent of tail pages and amalgamate them. Holding a ref on
the head also secures the tails.
Which also means most of what I was suggesting isn't going to work
anyhow.
Jason