On Fri, Aug 27, 2021 at 03:58:13PM +0100, Joao Martins wrote: > @@ -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