On Wed, Jul 22, 2026 at 11:40:06AM -0400, Gregory Price wrote:
> On Wed, Jul 22, 2026 at 10:20:00PM +0800, Richard Cheng wrote:
> >
> > I saw the reply in patch 5, so in fact there's not only one
> > dedicate zonelist, but numerous ?
> > I raise the question because zonelist was supposed to be a
> > global, unbypasssable thing in MM design, but now what you
> > are trying to do is to seperate the whole global list into several
> > parts ?
> >
> > Can you explain why in current design you don't consider to support
> > something like ZONELIST_PRIVATE[n]={0, .. ,n-1} ? that's my imagination
> > of what a global zonelist should look like, no matter private or non.
> >
>
> First let me say that there's nothing that prevents us from doing this,
> and we *could* make this the default case - but this decision was
> intentional by me.
>
You caught me on something here - I am wrong about my own code.
I described to you how I originally implemented zonelist isolation,
which I walked back when I was testing mempolicy and demotion.
The current code and the comments in the code are correct, we get
the following zonelists.
N_MEMORY : 0,1
N_MEMORY_PRIVATE: 2,3
ZONELIST_PRIVATE[0] = {0,1,2,3}
ZONELIST_PRIVATE[1] = {1,0,2,3}
ZONELIST_PRIVATE[2] = {2,0,1,3}
ZONELIST_PRIVATE[3] = {3,0,1,2}
Meaning everything except for MPOL_F_RELATIVE_NODES works (because
of cpuset isolation, but more on this in a moment).
So what I shipped here is what you are describing.
Looking back at my notes - I realized a few things that lead me to
walk back that isolation:
1) mempolicy makes more sense this way.
2) reclaim/demotion is easier to implement without isolation.
3) The individual service checks and nodelists handle the rest.
4) It overally just makes more sense. If something breaks isolation
it's because there's a bug, not because of a structural issue.
For example in demotion we do this:
demote_folio_list():
/* Get demotion targets, find the best one, and demote */
node_get_allowed_targets(pgdat, &allowed_mask);
target_nid = next_demotion_node(pgdat->node_id, &allowed_mask);
migrate_pages(demote_folios, alloc_demote_folio, ...);
Where the first step already filters on CAP_DEMOTION.
The result is still clean - no special iterators needed.
What I realized from your questions here is that since i walked back the
zonelist isolation, I think i can actually include any CAP_USER_NUMA
node in cpuset.mems and allow parititioning fairly trivially.
I think this might be the last majority complexity falling out.
Thank you for the questions - this has helped.
~Gregory