Skip to content

Commit 388d780

Browse files
committed
sched/numa: add statistics of numa balance task
JIRA: https://issues.redhat.com/browse/RHEL-110301 commit ad6b26b Author: Chen Yu <yu.c.chen@intel.com> Date: Fri May 23 20:51:15 2025 +0800 sched/numa: add statistics of numa balance task On systems with NUMA balancing enabled, it has been found that tracking task activities resulting from NUMA balancing is beneficial. NUMA balancing employs two mechanisms for task migration: one is to migrate a task to an idle CPU within its preferred node, and the other is to swap tasks located on different nodes when they are on each other's preferred nodes. The kernel already provides NUMA page migration statistics in /sys/fs/cgroup/mytest/memory.stat and /proc/{PID}/sched. However, it lacks statistics regarding task migration and swapping. Therefore, relevant counts for task migration and swapping should be added. The following two new fields: numa_task_migrated numa_task_swapped will be shown in /sys/fs/cgroup/{GROUP}/memory.stat, /proc/{PID}/sched and /proc/vmstat. Introducing both per-task and per-memory cgroup (memcg) NUMA balancing statistics facilitates a rapid evaluation of the performance and resource utilization of the target workload. For instance, users can first identify the container with high NUMA balancing activity and then further pinpoint a specific task within that group, and subsequently adjust the memory policy for that task. In short, although it is possible to iterate through /proc/$pid/sched to locate the problematic task, the introduction of aggregated NUMA balancing activity for tasks within each memcg can assist users in identifying the task more efficiently through a divide-and-conquer approach. As Libo Chen pointed out, the memcg event relies on the text names in vmstat_text, and /proc/vmstat generates corresponding items based on vmstat_text. Thus, the relevant task migration and swapping events introduced in vmstat_text also need to be populated by count_vm_numa_event(), otherwise these values are zero in /proc/vmstat. In theory, task migration and swap events are part of the scheduler's activities. The reason for exposing them through the memory.stat/vmstat interface is that we already have NUMA balancing statistics in memory.stat/vmstat, and these events are closely related to each other. Following Shakeel's suggestion, we describe the end-to-end flow/story of all these events occurring on a timeline for future reference: The goal of NUMA balancing is to co-locate a task and its memory pages on the same NUMA node. There are two strategies: migrate the pages to the task's node, or migrate the task to the node where its pages reside. Suppose a task p1 is running on Node 0, but its pages are located on Node 1. NUMA page fault statistics for p1 reveal its "page footprint" across nodes. If NUMA balancing detects that most of p1's pages are on Node 1: 1.Page Migration Attempt: The Numa balance first tries to migrate p1's pages to Node 0. The numa_page_migrate counter increments. 2.Task Migration Strategies: After the page migration finishes, Numa balance checks every 1 second to see if p1 can be migrated to Node 1. Case 2.1: Idle CPU Available If Node 1 has an idle CPU, p1 is directly scheduled there. This event is logged as numa_task_migrated. Case 2.2: No Idle CPU (Task Swap) If all CPUs on Node1 are busy, direct migration could cause CPU contention or load imbalance. Instead: The Numa balance selects a candidate task p2 on Node 1 that prefers Node 0 (e.g., due to its own page footprint). p1 and p2 are swapped. This cross-node swap is recorded as numa_task_swapped. Link: https://lkml.kernel.org/r/d00edb12ba0f0de3c5222f61487e65f2ac58f5b1.1748493462.git.yu.c.chen@intel.com Link: https://lkml.kernel.org/r/7ef90a88602ed536be46eba7152ed0d33bad5790.1748002400.git.yu.c.chen@intel.com Signed-off-by: Chen Yu <yu.c.chen@intel.com> Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> Tested-by: Madadi Vineeth Reddy <vineethr@linux.ibm.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com> Cc: Aubrey Li <aubrey.li@intel.com> Cc: Ayush Jain <Ayush.jain3@amd.com> Cc: "Chen, Tim C" <tim.c.chen@intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Libo Chen <libo.chen@oracle.com> Cc: Mel Gorman <mgorman <mgorman@suse.de> Cc: Michal Hocko <mhocko@kernel.org> Cc: Michal Koutný <mkoutny@suse.com> Cc: Muchun Song <muchun.song@linux.dev> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Phil Auld <pauld@redhat.com>
1 parent 4e424b8 commit 388d780

File tree

7 files changed

+27
-2
lines changed

7 files changed

+27
-2
lines changed

Documentation/admin-guide/cgroup-v2.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,12 @@ The following nested keys are defined.
16471647
numa_hint_faults (npn)
16481648
Number of NUMA hinting faults.
16491649

1650+
numa_task_migrated (npn)
1651+
Number of task migration by NUMA balancing.
1652+
1653+
numa_task_swapped (npn)
1654+
Number of task swap by NUMA balancing.
1655+
16501656
pgdemote_kswapd
16511657
Number of pages demoted by kswapd.
16521658

include/linux/sched.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ struct sched_statistics {
544544
u64 nr_failed_migrations_running;
545545
u64 nr_failed_migrations_hot;
546546
u64 nr_forced_migrations;
547+
#ifdef CONFIG_NUMA_BALANCING
548+
u64 numa_task_migrated;
549+
u64 numa_task_swapped;
550+
#endif
547551

548552
u64 nr_wakeups;
549553
u64 nr_wakeups_sync;

include/linux/vm_event_item.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
6464
NUMA_HINT_FAULTS,
6565
NUMA_HINT_FAULTS_LOCAL,
6666
NUMA_PAGE_MIGRATE,
67+
NUMA_TASK_MIGRATE,
68+
NUMA_TASK_SWAP,
6769
#endif
6870
#ifdef CONFIG_MIGRATION
6971
PGMIGRATE_SUCCESS, PGMIGRATE_FAIL,

kernel/sched/core.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,6 +3333,10 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
33333333
#ifdef CONFIG_NUMA_BALANCING
33343334
static void __migrate_swap_task(struct task_struct *p, int cpu)
33353335
{
3336+
__schedstat_inc(p->stats.numa_task_swapped);
3337+
count_vm_numa_event(NUMA_TASK_SWAP);
3338+
count_memcg_event_mm(p->mm, NUMA_TASK_SWAP);
3339+
33363340
if (task_on_rq_queued(p)) {
33373341
struct rq *src_rq, *dst_rq;
33383342
struct rq_flags srf, drf;
@@ -7839,8 +7843,9 @@ int migrate_task_to(struct task_struct *p, int target_cpu)
78397843
if (!cpumask_test_cpu(target_cpu, p->cpus_ptr))
78407844
return -EINVAL;
78417845

7842-
/* TODO: This is not properly updating schedstats */
7843-
7846+
__schedstat_inc(p->stats.numa_task_migrated);
7847+
count_vm_numa_event(NUMA_TASK_MIGRATE);
7848+
count_memcg_event_mm(p->mm, NUMA_TASK_MIGRATE);
78447849
trace_sched_move_numa(p, curr_cpu, target_cpu);
78457850
return stop_one_cpu(curr_cpu, migration_cpu_stop, &arg);
78467851
}

kernel/sched/debug.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,10 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns,
11891189
P_SCHEDSTAT(nr_failed_migrations_running);
11901190
P_SCHEDSTAT(nr_failed_migrations_hot);
11911191
P_SCHEDSTAT(nr_forced_migrations);
1192+
#ifdef CONFIG_NUMA_BALANCING
1193+
P_SCHEDSTAT(numa_task_migrated);
1194+
P_SCHEDSTAT(numa_task_swapped);
1195+
#endif
11921196
P_SCHEDSTAT(nr_wakeups);
11931197
P_SCHEDSTAT(nr_wakeups_sync);
11941198
P_SCHEDSTAT(nr_wakeups_migrate);

mm/memcontrol.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ static const unsigned int memcg_vm_event_stat[] = {
468468
NUMA_PAGE_MIGRATE,
469469
NUMA_PTE_UPDATES,
470470
NUMA_HINT_FAULTS,
471+
NUMA_TASK_MIGRATE,
472+
NUMA_TASK_SWAP,
471473
#endif
472474
};
473475

mm/vmstat.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,8 @@ const char * const vmstat_text[] = {
13401340
"numa_hint_faults",
13411341
"numa_hint_faults_local",
13421342
"numa_pages_migrated",
1343+
"numa_task_migrated",
1344+
"numa_task_swapped",
13431345
#endif
13441346
#ifdef CONFIG_MIGRATION
13451347
"pgmigrate_success",

0 commit comments

Comments
 (0)