From: Jianyong Wu <wujianyong@hygon.cn>
To: Tim Chen <tim.c.chen@linux.intel.com>,
Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Chen Yu <yu.c.chen@intel.com>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>,
Shrikanth Hegde <sshegde@linux.ibm.com>,
Phil Auld <pauld@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
"David Hildenbrand" <david@kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"jianyong.wu@outlook.com" <jianyong.wu@outlook.com>,
Yuan Zhong <zhongyuan@hygon.cn>, Huangsj <huangsj@hygon.cn>,
Fengyu Wang <wangfengyu@hygon.cn>,
Zhiwei Ying <yingzhiwei@hygon.cn>,
"justin.he@arm.com" <justin.he@arm.com>
Subject: RE: [RFC PATCH v2 02/23] sched/topology: Introduce a NUMA distance matrix with unique distance values
Date: Mon, 28 Sep 2026 09:39:01 +0000 [thread overview]
Message-ID: <8a0c239b5bdf40c99b645087dec8fd18@hygon.cn> (raw)
In-Reply-To: <112e526b4013e23c70adf5b8883db8e75358b473.camel@linux.intel.com>
Hi Tim,
> -----Original Message-----
> From: Tim Chen <tim.c.chen@linux.intel.com>
> Sent: Thursday, September 24, 2026 11:46 PM
> To: Jianyong Wu <wujianyong@hygon.cn>; Peter Zijlstra
> <peterz@infradead.org>
> Cc: Ingo Molnar <mingo@redhat.com>; Juri Lelli <juri.lelli@redhat.com>;
> Vincent Guittot <vincent.guittot@linaro.org>; Chen Yu
> <yu.c.chen@intel.com>; Dietmar Eggemann
> <dietmar.eggemann@arm.com>; Steven Rostedt <rostedt@goodmis.org>;
> Ben Segall <bsegall@google.com>; Mel Gorman <mgorman@suse.de>;
> Valentin Schneider <vschneid@redhat.com>; K Prateek Nayak
> <kprateek.nayak@amd.com>; Shrikanth Hegde <sshegde@linux.ibm.com>;
> Phil Auld <pauld@redhat.com>; Andrew Morton
> <akpm@linux-foundation.org>; David Hildenbrand <david@kernel.org>;
> linux-kernel@vger.kernel.org; linux-mm@kvack.org;
> jianyong.wu@outlook.com; Yuan Zhong <zhongyuan@hygon.cn>; Huangsj
> <huangsj@hygon.cn>; Fengyu Wang <wangfengyu@hygon.cn>; Zhiwei Ying
> <yingzhiwei@hygon.cn>; justin.he@arm.com
> Subject: Re: [RFC PATCH v2 02/23] sched/topology: Introduce a NUMA
> distance matrix with unique distance values
>
> On Thu, 2026-09-24 at 05:41 +0000, Jianyong Wu wrote:
> > >
> > > On Wed, 2026-09-23 at 03:14 +0000, Jianyong Wu wrote:
> > >
> > > [snip]
> > >
> > > > > >
> > > > >
> > > > How should the next closest NUMA node be selected when multiple
> > > nodes
> > > > have the same distance from the current node?
> > >
> > > You could use some other means like node id or load in the node
> > > if there's a tie in distance.
> > >
> > > >
> > > > That is the ambiguity this patch is intended to resolve. For each
> > > > source node, it disambiguates equal NUMA distances and produces a
> > > > unique node-level affinity ordering. An llc_next array can describe
> > > > the traversal of LLCs within a node, but it does not determine which
> > > > equidistant NUMA node should be visited next.
> > > >
> > >
> > > Agreed that llc_next only covers intra-node traversal and that you still
> > > need an inter-node order for the equidistant case. But I think
> > > sorting each source node's row by (distance, node_id)
> > > already gives a stable total order; the node id breaks the tie. You can
> > > also break it by node load if you'd rather balance than pin. Either way
> > > no new distance value has to be invented.
> > >
> >
> > Yes, using (distance, node_id) pairs is a straightforward way to order
> nodes,
> > similar to the memory zonelist fallback node sequence. I once
> considered
> > adopting this approach, but dropped the idea after realizing it lacks
> > symmetry.
> >
>
> Ordering symmetry can be resolved by looking at (distance, abs(node_id_i -
> node_id_j)).
>
> > For instance, node_affinity_distance(A, B) is not guaranteed to equal
> > node_affinity_distance(B, A).
>
> node distance is symmetric if you don't modify it.
>
OK, So, What about using a triple (distance, abs(node_id_i - node_id_j), min(i, j))
to rank node-affinity sequences? The third component is what makes it a total
order - given the distance, the gap and the smaller node id, the pair is
determined - so it guarantees deduplication and symmetry without inventing any
new distance value.
> >
> > The dedup algorithm can enforce this symmetry property for the
> resulting
> > node‑distance matrix.
> >
> > > > > This will be storage efficient and more straight forward
> > > > > to use than maintaining an artificial cache distance matrix.
> > > > >
> > > > > I dislike the artificial distance matrix also for the
> > > > > reason that there is no guarantee that there are enough
> > > > > available distance slots between two nodes. Say if I
> > > > > start with
> > > > >
> > > > > NODE0 NODE1 NODE2 NODE3
> > > > > NODE0 10 20 20 30
> > > > > NODE1 20 10 20 25
> > > > > NODE2 20 20 10 20
> > > > > NODE3 30 25 20 10
> > > > >
> > > > > and there are 16 LLCs in NODE 1, I will run
> > > > > out of slots when I try to deduplicate as
> > > > > only 10 slots are available to fit 16 LLCs.
> > > > >
> > > >
> > > > There is no system-wide LLC distance matrix in this series. The
> > > > de-duplication is applied only to the NUMA-node distance matrix.
> > > > Consequently, the number of LLCs in NODE1 does not affect the
> number
> > > > of distance values required by this patch.
> > > >
> > > > The algorithm also takes the available distance space into account
> > > > when assigning the refined node distances. It does not simply insert
> > > > one value for each duplicate into the existing gap between two
> > > > original distance levels. The distance values are adjusted as
> > > > necessary to reserve enough space before the duplicates are
> assigned.
> > > > Therefore, the algorithm cannot run out of available distance values,
> > > > regardless of the number of nodes sharing the same original
> distance.
> > > >
> > >
> > > Fair - you're right that the dedup is node-granularity, so my 16-LLC
> > > example doesn't apply as I stated it, and I'll drop that objection. It's
> > > moot anyway under the argument below: if the ordering uses raw
> distance
> > > plus a tie-break, and the score uses raw distance, then there's no
> matrix
> > > to pack in the first place and the "enough slots" question disappears.
> > >
> > > > In addition to providing the node-level component of the LLC affinity
> > > > ordering, the refined node distances are used to calculate the
> > > > affinity improvement score when selecting a source scheduling group
> > > > or runqueue during load balancing. Please see patch 12 for that
> usage.
> > >
> > > This affinity computation is where I think the dedup actually hurts
> rather
> > > than
> > > helps. The score in patch 12 is
> > >
> > > Di = dist(src_node, i) - dist(dst_node, i) (kept only if Di > 0)
> > > p = sum_i numa_counts[i] * clamp(Di, 4, 1024)
> > >
> > > so it reads the distance *magnitude*, not just the order. Feeding it the
> > > refined values manufactures gains on exactly the node pairs the dedup
> > > perturbed - the equidistant ones. Using your node matrices:
> > >
> > > raw: refined:
> > > N0 N1 N2 N3 N0 N1 N2 N3
> > > N0 10 20 20 30 N0 10 15 20 30
> > > N1 20 10 20 25 N1 15 10 12 25
> > > N2 20 20 10 20 N2 20 12 10 15
> > > N3 30 25 20 10 N3 30 25 15 10
> > >
> > > Scenario A - a locality-neutral pull gets a fabricated gain.
> > > Dest CPU on N1, source rq on N0, 5 tasks preferring N2:
> > >
> > > dist(N0,N2) dist(N1,N2) Di contribution
> > > raw 20 20 0 5 * 0 = 0
> > > refined 20 12 8 5 * 8 = 40
> > >
> > > N0 and N1 are physically equidistant from N2 (both 20), so pulling
> those
> > > tasks to N1 buys zero locality - raw correctly gives 0. Refined scores it
> > > 40 and the balancer may drag all 5 over chasing a gain that isn't there.
> > >
> > > Scenario B - two physically identical options get fake-ranked. Dest on
> > > N1; candidate sources N0 and N3, each holding only N2-preferring
> tasks:
> > >
> > > raw Di refined Di after clamp(.,4,1024)
> > > X (N0) 20-20=0 20-12=8 8
> > > Y (N3) 20-20=0 15-12=3 4
> > >
> > > Raw Di says both are 0, i.e. locality-equivalent, and load should decide.
> > > Refined ranks X over Y purely from invented deltas - and the clamp
> floor
> > > even promotes Y's fabricated 3 up to 4.
> > >
> > > Note the dedup only ever perturbs ties, so the skew is confined to
> > > equidistant pairs - which is exactly the case where there is no real
> > > locality difference and load should have been the tiebreaker.
> > >
> >
> > My intention is to distinguish equal node distances and give a definitely
> > task move direction.
> > What we want to do is aggregate task to as small area as possible. If N2
> is
> > Preferred node, and N2 is saturate, N1 is the next node of N2 in the
> > affinity node order, it's natural that prefer N1 than N0 for task
> aggregation,
> > right? Thus, we should give weight for task in N0. So N0 is more likely to
> be
> > chosen and migrate task to N1. Consequently, the task can more likely
> > aggregate to N1 and not evenly spread in the two nodes.
>
> I think you should get true affinity metric based on real distance. Bias
> based on node
> property can be applied separately and a easily controlled manner. That
> has the advantage
> of setting the bias based on factors like load or others.
>
> It is a bad design to have to tune a hacked up
> distance to change the bias. It is hard to control
> the magnitude of the bias and use a similar and consistent
> bias with the current approach. The distance you inject to
> disambiguate is not the same from node to node.
>
Makes sense. So, what about the following solution?
Given a node affinity sequence, a move from src to dst improves the
affinity of every task whose preferred node i ranks dst better than src. The score
is then
Di = raw_dist(src, i) - raw_dist(dst, i)
affinity_bias_i = position of src minus position of dst in node i's affinity
sequence, counted among the nodes at the same distance from
i (zero when Di is not zero)
p = sum_i {numa_counts[i] * (Di + affinity_bias_i)}, kept only if (Di + affinity_bias_i) > 0
When raw_dist(src, i) equals raw_dist(dst, i), Di is zero and the candidate is
selected purely by the affinity bias.
I would rather keep it fixed than let load decide. Load changes between passes,
so the choice can flip and the same tasks can be pulled back - not every time, but
it is the direction the aggregation is fighting against. At the node level,
equidistant nodes are indistinguishable to the metric, so the order between them is
a convention in any case; I would just rather it be a fixed one.
> >
> > Also, give a preference between N0 and N1 can limit the task migration
> from
> > N1 to N0. By this way, we can achieve the goal that keep tasks inside N1.
> >
> > > Stepping back, the matrix is being asked to do two jobs at once:
> > >
> > > - ordering: only needs a deterministic total order, which
> > > raw distance + node-id tie-break already provides;
> > > - scoring: wants true magnitudes, which raw distance also
> provides
> > > (equidistant => Di = 0).
> > >
> > > The dedup is only necessary if one matrix has to serve both - and that
> > > coupling is precisely what injects the fake Di. So if you need a node
> > > ordering, I'd use the unaltered distance and break ties by some other
> > > means (node id, or load), and feed the score the raw distance too.
> > >
> >
> > Yes, the refined node distance serves both purposes mentioned above.
> Hence,
> > dedup is necessary for this patch series.
> >
> > Both affinity‑score calculation and migration control rely on a consistent
> > refined node distance matrix. To keep this consistent, we should avoid
> using
> > the default node distance for one objective while adopting a different
> > variant for another purpose.
> >
> > The only open design question is whether symmetric node distances are
> > strictly required. Symmetry is preferable but adds implementation
> > complexity, so this represents a trade‑off. If symmetry is unnecessary,
> > I can construct the node order following your approach using the
> > (node_distance, node_id) pair, which is significantly simpler than my
> > current implementation.
> >
> > Your question touches on the trickiest part of this patch series.
> >
>
> I think the design can be much simplified if you don't have to invent a new
> distance matrix.
>
OK, let me try to remove this artificial node distance.
Thanks
Jianyong
next prev parent reply other threads:[~2026-09-28 9:39 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 12:27 [RFC PATCH v2 00/23] sched: Scale cache-aware aggregation at LLC granularity Jianyong Wu
2026-08-27 12:27 ` [RFC PATCH v2 01/23] sched/topology: Add llc_to_node() to translate LLC id to NUMA node Jianyong Wu
2026-08-29 10:31 ` Peter Zijlstra
2026-08-31 9:43 ` Jianyong Wu
2026-08-27 12:27 ` [RFC PATCH v2 02/23] sched/topology: Introduce a NUMA distance matrix with unique distance values Jianyong Wu
2026-08-31 11:50 ` Peter Zijlstra
2026-09-01 6:57 ` Jianyong Wu
2026-09-01 7:13 ` Peter Zijlstra
2026-09-01 7:37 ` Jianyong Wu
2026-09-22 18:38 ` Tim Chen
2026-09-23 3:14 ` Jianyong Wu
2026-09-23 18:29 ` Tim Chen
2026-09-24 5:41 ` Jianyong Wu
2026-09-24 15:46 ` Tim Chen
2026-09-28 9:39 ` Jianyong Wu [this message]
2026-10-01 22:04 ` Tim Chen
2026-10-08 7:35 ` Jianyong Wu
2026-09-01 8:48 ` Peter Zijlstra
2026-09-02 7:11 ` Jianyong Wu
2026-08-27 12:27 ` [RFC PATCH v2 03/23] sched/topology: Introduce a macro to traverse node Jianyong Wu
2026-08-27 12:27 ` [RFC PATCH v2 04/23] sched/topology: Introduce a method to calculate the llc distance Jianyong Wu
2026-08-31 13:12 ` Peter Zijlstra
2026-08-27 12:27 ` [RFC PATCH v2 05/23] sched/topology: Introduce a macro to traverse LLC inside node Jianyong Wu
2026-08-27 12:27 ` [RFC PATCH v2 06/23] sched/topology: Add sd_node for the NODE sched domain Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 07/23] sched/cache: Prioritize preferred NUMA node selection over LLC selection Jianyong Wu
2026-08-31 13:16 ` Peter Zijlstra
2026-09-01 7:44 ` Jianyong Wu
2026-08-31 13:22 ` Peter Zijlstra
2026-09-01 8:05 ` Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 08/23] sched/topology: Introduce a per-CPU tasks NUMA preferred counter Jianyong Wu
2026-08-31 13:23 ` Peter Zijlstra
2026-09-01 8:14 ` Jianyong Wu
2026-08-31 13:24 ` Peter Zijlstra
2026-09-01 8:31 ` Jianyong Wu
2026-09-01 10:21 ` Peter Zijlstra
2026-09-01 13:02 ` Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 09/23] sched/cache: Account percpu sd task NUMA preference Jianyong Wu
2026-09-01 7:54 ` Peter Zijlstra
2026-09-01 8:41 ` Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 10/23] sched/topology: Add per-sd scratch for the load balance affinity score Jianyong Wu
2026-09-01 8:02 ` Peter Zijlstra
2026-09-01 11:55 ` Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 11/23] sched/cache: Introduce helpers for task migration decisions Jianyong Wu
2026-09-01 9:08 ` Peter Zijlstra
2026-09-02 5:08 ` Jianyong Wu
2026-09-01 11:32 ` Peter Zijlstra
2026-09-02 5:46 ` Jianyong Wu
2026-09-02 21:11 ` Tim Chen
2026-09-03 2:04 ` Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 12/23] sched/cache: Introduce rq affinity gain calculation Jianyong Wu
2026-09-01 9:58 ` Peter Zijlstra
2026-09-01 12:23 ` Jianyong Wu
2026-09-01 10:16 ` Peter Zijlstra
2026-09-01 12:34 ` Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 13/23] sched/cache: Pick optimal src rq/group using affinity promotion metric Jianyong Wu
2026-08-27 12:28 ` [RFC PATCH v2 14/23] sched/cache: Drop prefer_sibling restriction for llc_balance Jianyong Wu
2026-09-01 10:29 ` Peter Zijlstra
2026-09-01 13:25 ` Jianyong Wu
2026-08-28 1:58 ` [RFC PATCH v2 15/23] sched/cache: Judge migration eligibility in LLC granularity Jianyong Wu
2026-08-28 2:04 ` [RFC PATCH v2 16/23] sched/cache: Allow un-throttled active balance to spread out of a full LLC Jianyong Wu
2026-08-28 2:07 ` [RFC PATCH v2 17/23] sched/fair: Fine-granularity NUMA balancing Jianyong Wu
2026-09-01 12:47 ` Peter Zijlstra
2026-09-02 6:43 ` Jianyong Wu
2026-08-28 2:09 ` [RFC PATCH v2 18/23] sched/cache: Scan all prefer nodes in thread group Jianyong Wu
2026-08-28 2:10 ` [RFC PATCH v2 19/23] sched/cache: Remove preferred LLC/node check no longer needed Jianyong Wu
2026-08-28 2:11 ` [RFC PATCH v2 20/23] sched/cache: Estimate utilization of the whole thread group Jianyong Wu
2026-09-01 14:44 ` Peter Zijlstra
2026-09-08 7:43 ` Jianyong Wu
2026-08-28 2:13 ` [RFC PATCH v2 21/23] sched/cache: Spread workloads within an estimated LLC range Jianyong Wu
2026-08-28 2:14 ` [RFC PATCH v2 22/23] sched/cache: Walk the preferred node from the preferred LLC Jianyong Wu
2026-08-28 2:15 ` [RFC PATCH v2 23/23] sched/debug: Print task preferred LLC for scheduler debugging Jianyong Wu
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=8a0c239b5bdf40c99b645087dec8fd18@hygon.cn \
--to=wujianyong@hygon.cn \
--cc=akpm@linux-foundation.org \
--cc=bsegall@google.com \
--cc=david@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=huangsj@hygon.cn \
--cc=jianyong.wu@outlook.com \
--cc=juri.lelli@redhat.com \
--cc=justin.he@arm.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=pauld@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=sshegde@linux.ibm.com \
--cc=tim.c.chen@linux.intel.com \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
--cc=wangfengyu@hygon.cn \
--cc=yingzhiwei@hygon.cn \
--cc=yu.c.chen@intel.com \
--cc=zhongyuan@hygon.cn \
/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.