On 30/08/2023 16:07, Matthew Wilcox wrote: > On Wed, Aug 30, 2023 at 10:50:11AM +0100, Ryan Roberts wrote: >> +++ b/include/asm-generic/tlb.h >> @@ -246,11 +246,11 @@ struct mmu_gather_batch { >> struct mmu_gather_batch *next; >> unsigned int nr; >> unsigned int max; >> - struct page *pages[]; >> + struct pfn_range folios[]; > > I think it's dangerous to call this 'folios' as it lets you think that > each entry is a single folio. But as I understand this patch, you can > coagulate contiguous ranges across multiple folios. No that's not quite the case; each contiguous range only ever spans a *single* folio. If there are 2 contiguous folios, they will be represented as separate ranges. This is done so that we can subsequently do the per-folio operations without having to figure out how many folios are within each range - one range = one (contiguous part of a) folio. On naming, I was calling this variable "ranges" in v1 but thought folios was actually clearer. How about "folio_regions"? > >> -void free_pages_and_swap_cache(struct page **pages, int nr) >> +void free_folios_and_swap_cache(struct pfn_range *folios, int nr) >> { >> lru_add_drain(); >> for (int i = 0; i < nr; i++) >> - free_swap_cache(pages[i]); >> - release_pages(pages, nr); >> + free_swap_cache(pfn_to_page(folios[i].start)); > > ... but here, you only put the swapcache for the first folio covered by > the range, not for each folio. Yes that's intentional - one range only ever covers one folio, so I only need to call free_swap_cache() once for the folio. Unless I've misunderstood and free_swap_cache() is actually decrementing a reference count and needs to be called for every page? (but it doesn't look like that in the code). > >> + folios_put_refs(folios, nr); > > It's kind of confusing to have folios_put() which takes a struct folio * > and then folios_put_refs() which takes a struct pfn_range *. > pfn_range_put()? I think it's less confusing if you know that each pfn_range represents a single contig range of pages within a *single* folio. pfn_range_put() would make it sound like its ok to pass a pfn_range that spans multiple folios (this would break). I could rename `struct pfn_range` to `struct sub_folio` or something like that. Would that help make the semantic clearer?