On Thu, Dec 23, 2021 at 12:21:06AM +0000, Matthew Wilcox wrote:
On Wed, Dec 22, 2021 at 02:09:41PM +0100, David Hildenbrand wrote:
Right, from an API perspective we really want people to use FOLL_PIN.
To optimize this case in particular it would help if we would have the FOLL flags on the unpin path. Then we could just decide internally "well, short-term R/O FOLL_PIN can be really lightweight, we can treat this like a FOLL_GET instead". And we would need that as well if we were to keep different counters for R/O vs. R/W pinned.
FYI, in my current tree, there's a gup_put_folio() which replaces put_compound_head:
static void gup_put_folio(struct folio *folio, int refs, unsigned int flags) { if (flags & FOLL_PIN) { node_stat_mod_folio(folio, NR_FOLL_PIN_RELEASED, refs); if (hpage_pincount_available(&folio->page)) hpage_pincount_sub(&folio->page, refs); else refs *= GUP_PIN_COUNTING_BIAS; }
folio_put_refs(folio, refs);
}
That can become non-static if it's needed. I'm still working on that series, because I'd like to get it to a point where we return one folio pointer instead of N page pointers. Not quite there yet.
I'm keen to see what that looks like, every driver I'm working on that calls PUP goes through gyrations to recover contiguous pages, so this is most welcomed!
Jason