Re: [PATCH RFC v2 0/3] mm: Properly document tail pages for a folio

From: Peter Xu
Date: Mon Aug 14 2023 - 16:23:26 EST


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?

>
> How about this?

I still prefer my version, sorry. But I agree this is better than nothing
to guide what's free to use - it's really not obvious to me, and I suppose
true to most people. Besides..

>
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 5e74ce4a28cd..873285bb5d45 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -334,11 +334,14 @@ struct folio {
> /* public: */
> unsigned char _folio_dtor;
> unsigned char _folio_order;
> + /* two bytes available here */
> atomic_t _entire_mapcount;
> atomic_t _nr_pages_mapped;
> atomic_t _pincount;
> + /* no more space on 32-bt */
> #ifdef CONFIG_64BIT
> unsigned int _folio_nr_pages;
> + /* twelve bytes available on 64-bit */
> #endif
> /* private: the union with struct page is transitional */
> };
> @@ -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 can figure it out in ten seconds now with my documents..

* |--------+-------------+-------------------|
* | index | 32 bits | 64 bits |
* |--------+-------------+-------------------|
* | 0 | flags | flags |
* | 1 | head | head |
* | 2 | FREE | FREE |
* | 3 | FREE [1] | FREE [1] |
* | 4 | FREE | FREE |
* | 5 | FREE | private [2] |
* | 6 | mapcnt | mapcnt+refcnt [3] |
* | 7 | refcnt [3] | |
* |--------+-------------+-------------------|

Then...

/* public: WORD 2-3 */
struct list_head _deferred_list;
<----- so after this we have WORDs 4/5 free on 32bits and 4 only on
64 bits, because WORD 5 is used on 64bits

... but I won't be able to if without these documents. I hope it justifies
that it's still worthwhile.

Thanks,

--
Peter Xu