On Mon, Aug 14, 2023 at 04:21:55PM -0400, Peter Xu wrote: > On Mon, Aug 14, 2023 at 08:58:44PM +0100, Matthew Wilcox wrote: > > On Mon, Aug 14, 2023 at 02:44:08PM -0400, Peter Xu wrote: > > > > Look, this is all still too complicated. And you're trying to make > > something better that I'm trying to make disappear. I'd really rather > > you spent your time worrying about making userfaultfd use folios > > than faffing with this. > > I saw that internally some of uffd already start to use folio, while I > don't think the syscall part needs changing yet - the ranged API should > work for folio when it comes, and other than that folio should be hidden > and transparent, afaiu. > > Do you mean when large folios can land on anon/shmem we can start to > allocate large folios there for uffd operations? Or something else? Hm, I thought there were some parts that still needed to be converted. But I don't see anything obvious right now. > > @@ -360,6 +363,7 @@ struct folio { > > unsigned long _head_2a; > > /* public: */ > > struct list_head _deferred_list; > > + /* three more words available here */ > > .. not really three more words here but 2 for 32 bits and 1 for 64 bits. > In my patch 3 I used "8 bytes free" so it's applicable to both. I always forget about THP_SWAP using tail->private. That actually needs to be asserted by the compiler, not just documented. Something along these lines. diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 659c7b84726c..3880b3f2e321 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -340,8 +340,11 @@ struct folio { atomic_t _pincount; #ifdef CONFIG_64BIT unsigned int _folio_nr_pages; -#endif + /* 4 byte gap here */ /* private: the union with struct page is transitional */ + /* Fix THP_SWAP to not use tail->private */ + unsigned long _private_1; +#endif }; struct page __page_1; }; @@ -362,6 +365,9 @@ struct folio { /* public: */ struct list_head _deferred_list; /* private: the union with struct page is transitional */ + unsigned long _avail_2a; + /* Fix THP_SWAP to not use tail->private */ + unsigned long _private_2a; }; struct page __page_2; }; @@ -386,12 +392,18 @@ FOLIO_MATCH(memcg_data, memcg_data); offsetof(struct page, pg) + sizeof(struct page)) FOLIO_MATCH(flags, _flags_1); FOLIO_MATCH(compound_head, _head_1); +#ifdef CONFIG_64BIT +FOLIO_MATCH(private, _private_1); +#endif #undef FOLIO_MATCH #define FOLIO_MATCH(pg, fl) \ static_assert(offsetof(struct folio, fl) == \ offsetof(struct page, pg) + 2 * sizeof(struct page)) FOLIO_MATCH(flags, _flags_2); FOLIO_MATCH(compound_head, _head_2); +FOLIO_MATCH(flags, _flags_2a); +FOLIO_MATCH(compound_head, _head_2a); +FOLIO_MATCH(private, _private_2a); #undef FOLIO_MATCH /* This is against the patchset I just posted which frees up a word in the first tail page.