Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jianyong Wu" <wujianyong@hygon.cn>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Juri Lelli" <juri.lelli@redhat.com>,
	"Vincent Guittot" <vincent.guittot@linaro.org>,
	"Chen Yu" <yu.c.chen@intel.com>,
	"Tim Chen" <tim.c.chen@linux.intel.com>
Cc: "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>,
	maddy@linux.ibm.com, "Michael Ellerman" <mpe@ellerman.id.au>,
	ljs@kernel.org, linux-mm@kvack.org, jianyong.wu@outlook.com,
	zhongyuan@hygon.cn, huangsj@hygon.cn, wangfengyu@hygon.cn,
	yingzhiwei@hygon.cn
Subject: Re: [RFC PATCH v3 08/17] sched/cache: Introduce helpers for task migration decisions
Date: Fri, 30 Oct 2026 03:04:58 +0000	[thread overview]
Message-ID: <sashiko-outbox-190202@kernel.org> (raw)
In-Reply-To: <20261029022036.4002331-9-wujianyong@hygon.cn>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] sched/cache: can_migrate_llcs() misapplies node walk when dst precedes src
--

commit c7cd924467c2448429791ac003c69c23764da05a
Author: Jianyong Wu <wujianyong@hygon.cn>

sched/cache: Introduce helpers for task migration decisions

This commit introduces get_node_stats(), can_migrate_llcs(), and
if_to_prefer(), and extends fits_llc_capacity() to support cache-aware task
migration decisions across multiple LLCs and NUMA nodes.

> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index fe357d79b6e06..4eb7cede9080f 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c

[ ... ]

> @@ -10614,13 +10617,185 @@ static enum llc_mig can_migrate_llc(int src_cpu, int dst_cpu,

[ ... ]

> +static enum llc_mig __maybe_unused can_migrate_llcs(int src_cpu, int dst_cpu,
> +				     struct task_struct *p, bool to_pref)
> +{
> +	unsigned long src_util, src_pre, src_cap, dst_util, dst_cap, dst_pre;
> +	int target_node, src_node, dst_node, dst_distance;
> +	int node, target_cpu = src_cpu, n_llc;
> +	unsigned long tsk_util = 0;
> +	bool got_src = false;
> +
> +	if (!get_llc_stats(src_cpu, &src_util, &src_cap) ||
> +	    !get_llc_stats(dst_cpu, &dst_util, &dst_cap))
> +		return mig_unrestricted;
> +
> +	if (p) {
> +		struct mm_struct *mm = p->mm;
> +
> +		if (mm)
> +			target_cpu = READ_ONCE(mm->sc_stat.cpu);
> +		target_cpu = target_cpu >= 0 ? target_cpu : src_cpu;
> +
> +		tsk_util = task_util(p);
> +	}

[ ... ]

> +	src_node = cpu_to_node(src_cpu);
> +	dst_node = cpu_to_node(dst_cpu);
> +	target_node = cpu_to_node(target_cpu);
> +	dst_distance = node_distance(target_node, dst_node);
> +
> +	/*
> +	 * For moves away from the cache preferred node, examine the source,
> +	 * intervening nodes and destination in the cached affinity order.
> +	 */
> +	for_each_affi_node(target_cpu, node) {
> +		unsigned long nu = 0, nc = 0;
> +
> +		if (!got_src) {
> +			if (node != src_node)
> +				continue;
> +			got_src = true;

[ ... ]

> +			/* Cross-node moves must leave the source node filled. */
> +			if (get_node_stats(src_node, &nu, &nc, &n_llc) && n_llc) {
> +				nu = nu < tsk_util ? 0 : nu - tsk_util;
> +				if (fits_llc_capacity(nu, nc, false))
> +					return mig_forbid;
> +			}
> +			continue;
> +		}
> +
> +		if (node != dst_node) {
> +			if (!get_node_stats(node, &nu, &nc, &n_llc) || !n_llc)
> +				continue;
> +
> +			/*
> +			 * Estimate average LLC headroom in intervening nodes.
> +			 * Charge one task per LLC, or per pair of LLCs when
> +			 * this node is closer to the target than the destination.
> +			 */
> +			if (node_distance(target_node, node) < dst_distance)
> +				nu += DIV_ROUND_UP(n_llc, 2) * tsk_util;
> +			else
> +				nu += n_llc * tsk_util;
> +
> +			if (fits_llc_capacity(nu, nc, true))
> +				return mig_forbid;
> +			continue;
> +		}
> +
> +		if (fits_llc_capacity(dst_util, dst_cap, true))
> +			return mig_llc;
> +
> +		if (util_greater(src_pre, dst_pre) && src_util >= dst_util)
> +			return mig_llc;
> +
> +		break;
> +	}

[Severity: Medium]
In kernel/sched/fair.c, what happens in can_migrate_llcs() when to_pref is
false and src_node != dst_node, yet dst_node precedes src_node in the
for_each_affi_node(target_cpu, node) walk?

The loop skips every node before src_node while got_src is false, so
dst_node is passed before got_src becomes true. Once node == src_node sets
got_src = true, every subsequent node in the affinity sequence satisfies
node != dst_node. Those trailing nodes are then evaluated as intervening
nodes and can veto the move with mig_forbid, while the destination checks at
node == dst_node are never reached, contrary to the commit message guarantee
that nodes following the destination do not participate in the decision.

When wired up to can_migrate_llc_task() and alb_break_llc() in the
subsequent commit ("sched/cache: Apply multi-LLC aggregation policy to task
migration"), dst_node can precede src_node in target_cpu's affinity order
even when to_pref is false in several cases:

1. Both can_migrate_llc_task() and alb_break_llc() read mm->sc_stat.cpu once
   to compute pref_llc for if_to_prefer(), and can_migrate_llcs() reads
   mm->sc_stat.cpu a second time via READ_ONCE(mm->sc_stat.cpu). A
   concurrent update in task_cache_work() or account_mm_sched() can cause
   if_to_prefer() to return false for the old CPU while can_migrate_llcs()
   reads a new target_cpu whose target_node ranks dst_node before src_node.

2. In alb_break_llc(), pref_llc is only derived from mm->sc_stat.cpu when
   cur->sched_class == &fair_sched_class (otherwise remaining -1 so
   if_to_prefer() returns false), whereas can_migrate_llcs() unconditionally
   reads target_cpu = READ_ONCE(p->mm->sc_stat.cpu).

3. In if_to_prefer(), llc_to_node(pref_llc) can return -1 (for example, if
   rebuild_llc_node_map() failed allocation), causing if_to_prefer() to
   return false while can_migrate_llcs() resolves target_node via
   cpu_to_node(target_cpu) and walks for_each_affi_node(target_cpu, node).

Should the caller pass a single consistent target_cpu or preferred node to
both helpers, or should can_migrate_llcs() handle encountering dst_node
before src_node during the affinity walk?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261029022036.4002331-1-wujianyong@hygon.cn?part=8


  reply	other threads:[~2026-10-30  3:05 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29  2:20 [RFC PATCH v3 00/17] sched: Scale cache-aware aggregation at LLC granularity Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 01/17] sched/topology: Add llc_to_node() to translate LLC ID to NUMA node Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 02/17] sched/topology: Build NUMA node affinity sequences Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 03/17] sched/topology: Add an iterator for cached NUMA node affinity rows Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 04/17] sched/topology: Build triangular affinity orders for LLCs in a node Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 05/17] sched/topology: Walk LLCs in NUMA node Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 06/17] sched/cache: Prioritize cache-preferred node selection over LLC selection Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 07/17] sched/topology: Add per-sd scratch for cache-aware load balancing Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 08/17] sched/cache: Introduce helpers for task migration decisions Jianyong Wu
2026-10-30  3:04   ` sashiko-bot [this message]
2026-10-29  2:20 ` [RFC PATCH v3 09/17] sched/cache: Introduce rq affinity gain calculation Jianyong Wu
2026-10-30  3:05   ` sashiko-bot
2026-10-29  2:20 ` [RFC PATCH v3 10/17] sched/cache: Pick the source rq/group with the highest affinity gain Jianyong Wu
2026-10-30  3:05   ` sashiko-bot
2026-10-29  2:20 ` [RFC PATCH v3 11/17] sched/cache: Drop prefer_sibling restriction for llc_balance Jianyong Wu
2026-10-29  2:20 ` [RFC PATCH v3 12/17] sched/cache: Apply multi-LLC aggregation policy to task migration Jianyong Wu
2026-10-30  3:05   ` sashiko-bot
2026-10-29  2:45 ` [RFC PATCH v3 13/17] sched/cache: Allow active balance to spread load from a full LLC Jianyong Wu
2026-10-30  3:05   ` sashiko-bot
2026-10-29  2:50 ` [RFC PATCH v3 14/17] sched/cache: Consider LLC load when selecting a single-task source rq Jianyong Wu
2026-10-29  2:56 ` [RFC PATCH v3 15/17] sched/cache: Include recently used preferred nodes in LLC scans Jianyong Wu
2026-10-30  3:05   ` sashiko-bot
2026-10-29  2:58 ` [RFC PATCH v3 16/17] sched/cache: Drop stale preferred LLC checks Jianyong Wu
2026-10-30  3:05   ` sashiko-bot
2026-10-29  2:59 ` [RFC PATCH v3 17/17] sched/debug: Show cache placement and preferred LLC in /proc/<pid>/sched 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=sashiko-outbox-190202@kernel.org \
    --to=sashiko-bot@kernel.org \
    --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=kprateek.nayak@amd.com \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=maddy@linux.ibm.com \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=pauld@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --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=wujianyong@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox