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

Reply via email to