All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: Zi Yan <ziy@nvidia.com>
Cc: "David Hildenbrand (Arm)" <david@kernel.org>,
	<intel-xe@lists.freedesktop.org>,
	<dri-devel@lists.freedesktop.org>, <linux-mm@kvack.org>,
	<linux-kernel@vger.kernel.org>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Christian Koenig <christian.koenig@amd.com>,
	 Huang Rui <ray.huang@amd.com>,
	Matthew Auld <matthew.auld@intel.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	"Baolin Wang" <baolin.wang@linux.alibaba.com>,
	"Liam R. Howlett" <liam@infradead.org>,
	Nico Pache <npache@redhat.com>,
	Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
	Barry Song <baohua@kernel.org>, Lance Yang <lance.yang@linux.dev>,
	Tvrtko Ursulin <tvrtko.ursulin@igalia.com>,
	"Dave Airlie" <airlied@redhat.com>,
	Matthew Wilcox <willy@infradead.org>
Subject: Re: [PATCH 1/3] mm/huge_memory: add folio_split_driver_managed()
Date: Mon, 27 Jul 2026 13:34:13 -0700	[thread overview]
Message-ID: <amfAxfD9257Md6Bn@gsse-cloud1.jf.intel.com> (raw)
In-Reply-To: <2FD2B991-09B3-40EE-8230-49BE3A239EEC@nvidia.com>

On Mon, Jul 27, 2026 at 02:23:33PM -0400, Zi Yan wrote:
> On 27 Jul 2026, at 13:33, David Hildenbrand (Arm) wrote:
> 
> > On 7/22/26 17:28, Zi Yan wrote:
> >> On Wed Jul 22, 2026 at 10:26 AM EDT, Zi Yan wrote:
> >>> On Wed Jul 22, 2026 at 12:42 AM EDT, Matthew Brost wrote:
> >>>> Add a lightweight structural split primitive for large (compound) folios
> >>>> that a driver allocated with __GFP_COMP and manages entirely by itself,
> >>>> outside of the core mm's view.
> >>>>
> >>>> The existing split paths - split_folio() and folio_split_unmapped() -
> >>>> are built for folios that the mm owns: they perform a refcount freeze,
> >>>> walk and remap the rmap, and take the anon_vma / i_mmap locks, and
> >>>> folio_split_unmapped() further assumes an anon, pagecache-style refcount
> >>>> model (nr_pages + 1). None of that applies to a folio that is:
> >>>>
> >>>>   - singly referenced (the caller holds the only reference),
> >>>>   - not mapped through the rmap (folio_mapped() == 0),
> >>>>   - not in the page cache or swap cache (folio->mapping == NULL),
> >>>>   - not on any LRU or the deferred-split list.
> >>>>
> >>>> For such a folio the split is purely structural: because nothing else in
> >>>> the kernel can reach it, there is no need to freeze the refcount or touch
> >>>> any mapping. folio_split_driver_managed() therefore performs only the
> >>>
> >>> I do not think so. PFN scanners like memory compaction should be able to
> >>> see them, unless you mean something else about "a driver allocated with
> >>> __GFP_COMP". You will need to freeze it to prevent the to-be-split
> >>> folios being touched by others.
> >>>
> >>>
> >>>> compound and split-accounting teardown via __split_unmapped_folio() and
> >>>> then hands each resulting order-@new_order folio its own reference,
> >>>> mirroring split_page() for compound folios. The caller keeps the original
> >>>> reference on the first resulting folio and is responsible for freeing all
> >>>> of them individually.
> >>>>
> >>>> The immediate user is TTM's GPU page pool, which allocates higher-order
> >>>> compound pages, maps them into userspace via VM_PFNMAP (never through the
> >>>> rmap), and needs to split them into order-0 folios under memory pressure
> >>>> so pages can be backed up to shmem and freed one at a time.
> >>>>
> >>>> A CONFIG_TRANSPARENT_HUGEPAGE=n stub is provided so callers can build
> >>>> without the split machinery; it warns and returns -EINVAL.
> >>>>
> >>>> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >>>> Cc: Maxime Ripard <mripard@kernel.org>
> >>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> >>>> Cc: David Airlie <airlied@gmail.com>
> >>>> Cc: Simona Vetter <simona@ffwll.ch>
> >>>> Cc: Christian Koenig <christian.koenig@amd.com>
> >>>> Cc: Huang Rui <ray.huang@amd.com>
> >>>> Cc: Matthew Auld <matthew.auld@intel.com>
> >>>> Cc: Matthew Brost <matthew.brost@intel.com>
> >>>> Cc: Andrew Morton <akpm@linux-foundation.org>
> >>>> Cc: David Hildenbrand <david@kernel.org>
> >>>> Cc: Lorenzo Stoakes <ljs@kernel.org>
> >>>> Cc: Zi Yan <ziy@nvidia.com>
> >>>> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> >>>> Cc: "Liam R. Howlett" <liam@infradead.org>
> >>>> Cc: Nico Pache <npache@redhat.com>
> >>>> Cc: Ryan Roberts <ryan.roberts@arm.com>
> >>>> Cc: Dev Jain <dev.jain@arm.com>
> >>>> Cc: Barry Song <baohua@kernel.org>
> >>>> Cc: Lance Yang <lance.yang@linux.dev>
> >>>> Cc: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
> >>>> Cc: Dave Airlie <airlied@redhat.com>
> >>>> Cc: dri-devel@lists.freedesktop.org
> >>>> Cc: linux-kernel@vger.kernel.org
> >>>> Cc: linux-mm@kvack.org
> >>>> Suggested-by: Matthew Wilcox <willy@infradead.org>
> >>>> Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> >>>> Assisted-by: GitHub-Copilot:claude-opus-4.8
> >>>>
> >>>> ---
> >>>>
> >>>> The patch is based on drm-tip rather than the core MM branches to
> >>>> facilitate Intel CI testing and initial review. It can be rebased onto
> >>>> the core MM branches in a subsequent revision.
> >>>> ---
> >>>>  include/linux/huge_mm.h |  8 ++++++
> >>>>  mm/huge_memory.c        | 63 +++++++++++++++++++++++++++++++++++++++++
> >>>>  2 files changed, 71 insertions(+)
> >>>>
> >>>> diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
> >>>> index ad20f7f8c179..35661d82d54a 100644
> >>>> --- a/include/linux/huge_mm.h
> >>>> +++ b/include/linux/huge_mm.h
> >>>> @@ -402,6 +402,7 @@ enum split_type {
> >>>>  int __split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
> >>>>  		unsigned int new_order);
> >>>>  int folio_split_unmapped(struct folio *folio, unsigned int new_order);
> >>>> +int folio_split_driver_managed(struct folio *folio, unsigned int new_order);
> >>>>  unsigned int min_order_for_split(struct folio *folio);
> >>>>  int split_folio_to_list(struct folio *folio, struct list_head *list);
> >>>>  int folio_check_splittable(struct folio *folio, unsigned int new_order,
> >>>> @@ -656,6 +657,13 @@ static inline int split_folio_to_list(struct folio *folio, struct list_head *lis
> >>>>  	return -EINVAL;
> >>>>  }
> >>>>
> >>>> +static inline int folio_split_driver_managed(struct folio *folio,
> >>>> +					     unsigned int new_order)
> >>>> +{
> >>>> +	VM_WARN_ON_ONCE_FOLIO(1, folio);
> >>>> +	return -EINVAL;
> >>>> +}
> >>>> +
> >>>>  static inline int folio_split(struct folio *folio, unsigned int new_order,
> >>>>  		struct page *page, struct list_head *list)
> >>>>  {
> >>>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> >>>> index 2bccb0a53a0a..06f9a5f35df8 100644
> >>>> --- a/mm/huge_memory.c
> >>>> +++ b/mm/huge_memory.c
> >>>> @@ -4185,6 +4185,69 @@ int folio_split_unmapped(struct folio *folio, unsigned int new_order)
> >>>>  	return ret;
> >>>>  }
> >>>>
> >>>> +/**
> >>>> + * folio_split_driver_managed() - split an exclusively-owned, off-LRU folio
> >>>> + * @folio: folio to split. Must be a large (compound) folio that is owned
> >>>> + *         exclusively by the caller and is invisible to the core mm.
> >>>> + * @new_order: the order of the folios after the split.
> >>>> + *
> >>>> + * This is a lightweight structural split for folios that a driver allocated
> >>>> + * and manages itself (for example TTM's GPU page pool, which allocates
> >>>> + * higher-order compound pages with __GFP_COMP and maps them into userspace
> >>>> + * via VM_PFNMAP rather than through the rmap). Such folios are:
> >>
> >> Strickly speaking, these vm_insert*() compound pages are not folios,
> >> since folios are supposed to be rmappable and they are either anonymous
> >> memory or file-backed memory. I am working on separating them from
> >> rmappable folios by replacing PG_private with PG_folio and marking all
> >> pages in a folio with PG_folio in page_rmappable_folio().
> >>
> >> Hopefully, we can find a better name, like refcounted_folio, later for
> >> these non-rmappable compound pages.
> >
> > They wouldn't really be folios, I guess. They would likely be a simple
> > "refcounted" memtype that allows for compound pages.
> 
> Yes, they are not folios. But “folio” was started to replace “compound page”
> and slowly becomes rmappable anon and file-backed. People outside MM still
> thinks “folio” == “compound page”. But once I manage to remove PG_private
> and get us PG_folio, page_folio() will return NULL for non-folio compound
> pages and we will need a new type for them, “refcounted_XXX”. We can decide
> XXX when I get there. :)
> 
> >
> > But what is the conclusion here? It sounds like "folio_split_" is the entirely
> > wrong interface for these compound pages.
> 
> We probably would allow folio_split() to be used on compound pages now
> until we can make a clean distinction, e.g., using PG_folio, between them.
> 
> Yes, folio_split() and its helper functions are meant for rmappable anon and
> file-backed folios. But currently “folio” is de facto “compound page”, since
> for example prep_compound_head() initializes folio fields even if it is meant
> only for compound pages.
> 
> After folio and compound page are separate concepts in the code base, probably
> we can think about how to have two split functions for them and still keep
> maximum code reuse. Namely, we could have split_compound() does the compound
> page split (e.g., copying page flags, adjust compound head/tail/order, etc.)
> and split_folio() calls split_compound() and perform extra folio operations.
> The details are TBD.

I like the idea of split_compound, ideally in mm/page_alloc.c, similar
to split_page(), which performs the mechanical splitting of compound
pages managed on the driver side (i.e., not mappable, not on an LRU,
protected by dma-resv in the case of DRM, etc.).

I got yelled at for not allocating these types of pages with GFP_COMP,
and I basically found that this missing MM primitive is what has
prevented that approach from being practical. Using GFP_COMP makes our
life quite a bit easier for managing these types of pages too, so it
would be great if we could get a solution for this.

So maybe I should drop this for now, keep an eye on the MM work, and
circle back once the missing primitive is implemented?

Thanks the help / insight,
Matt

> 
> Best Regards,
> Yan, Zi

  reply	other threads:[~2026-07-27 20:34 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22  4:42 [PATCH 1/3] mm/huge_memory: add folio_split_driver_managed() Matthew Brost
2026-07-22  4:42 ` [PATCH 2/3] drm/xe: select TRANSPARENT_HUGEPAGE Matthew Brost
2026-07-22  4:48   ` sashiko-bot
2026-07-22  4:42 ` [PATCH 3/3] drm/ttm: allocate pool pages as compound (__GFP_COMP) Matthew Brost
2026-07-22  4:58   ` sashiko-bot
2026-07-22  4:48 ` ✗ CI.KUnit: failure for series starting with [1/3] mm/huge_memory: add folio_split_driver_managed() Patchwork
2026-07-22 14:26 ` [PATCH 1/3] " Zi Yan
2026-07-22 15:28   ` Zi Yan
2026-07-27 17:33     ` David Hildenbrand (Arm)
2026-07-27 18:23       ` Zi Yan
2026-07-27 20:34         ` Matthew Brost [this message]
2026-07-28 12:58         ` David Hildenbrand (Arm)
2026-07-28 14:44           ` Lorenzo Stoakes (ARM)
2026-07-28 15:52             ` Zi Yan
2026-07-28 14:40 ` Lorenzo Stoakes (ARM)
2026-07-28 14:46   ` Lorenzo Stoakes (ARM)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=amfAxfD9257Md6Bn@gsse-cloud1.jf.intel.com \
    --to=matthew.brost@intel.com \
    --cc=airlied@gmail.com \
    --cc=airlied@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=christian.koenig@amd.com \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=lance.yang@linux.dev \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthew.auld@intel.com \
    --cc=mripard@kernel.org \
    --cc=npache@redhat.com \
    --cc=ray.huang@amd.com \
    --cc=ryan.roberts@arm.com \
    --cc=simona@ffwll.ch \
    --cc=tvrtko.ursulin@igalia.com \
    --cc=tzimmermann@suse.de \
    --cc=willy@infradead.org \
    --cc=ziy@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.