From: "Li Zhe" <lizhe.67@bytedance.com>
To: "Yafang Shao" <laoar.shao@gmail.com>, <ast@kernel.org>,
<daniel@iogearbox.net>, <andrii@kernel.org>, <eddyz87@gmail.com>,
<memxor@gmail.com>, <mingo@redhat.com>, <peterz@infradead.org>,
<juri.lelli@redhat.com>, <vincent.guittot@linaro.org>,
<akpm@linux-foundation.org>, <david@kernel.org>,
<gourry@gourry.net>, <tj@kernel.org>, <hannes@cmpxchg.org>,
<mkoutny@suse.com>, <shakeel.butt@linux.dev>,
<roman.gushchin@linux.dev>, <yu.c.chen@intel.com>,
<zhao1.liu@intel.com>, <tim.c.chen@linux.intel.com>
Cc: <bpf@vger.kernel.org>, <linux-mm@kvack.org>,
<cgroups@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH v3 bpf-next 0/5] BPF-based per-cgroup NUMA balancing mode selection
Date: Fri, 23 Oct 2026 14:32:08 +0800 [thread overview]
Message-ID: <f68e7f9e-6037-4087-b7cd-a17ea4dba279@bytedance.com> (raw)
In-Reply-To: <20261019064157.29885-1-laoar.shao@gmail.com>
On 10/19/26 2:41 PM, Yafang Shao wrote:
> The Problem
> ===========
>
> In our large fleet of Kubernetes-managed servers, NUMA balancing has
> been historically disabled globally on each server. With the increasing
> deployment of multi-socket AMD EPYC servers, cross-NUMA access has
> become a critical performance issue, which made us reconsider enabling NUMA
> balancing to address it.
>
> Enabling NUMA balancing globally is still not acceptable since it can
> introduce latency spikes for latency-sensitive workloads. What we need is
> to choose per workload whether NUMA balancing runs at all, and which mode
> it runs in. A latency-sensitive service wants NUMA balancing disabled,
> while a batch service wants its PMEM-resident memory promoted when hot
> without paying for scheduler-driven migration. No single global setting
> serves both.
>
> The Design
> ==========
>
> This series introduces the fine-grained per-cgroup NUMA balancing
> control. It grows out of Tejun's suggestion to store the existing
> NUMA_BALANCING_* bitmask per cgroup and expose it through BPF kfuncs.
> cgroup::numab_mode holds the request: NUMAB_FOLLOW_SYSTEM (-1) defers
> to the global sysctl state, anything else is a bitmask.
> bpf_numab_set_mode() writes a request, bpf_numab_get_mode() reads the
> combined request of the cgroup and of every ancestor back. The hot
> paths walk the same chain at read time behind a static key, so while no
> cgroup makes a request the overhead is one patched-out branch.
>
> An opt-out wins and binds the subtree: a DISABLED request anywhere in
> the chain opts the cgroup's tasks out entirely. Otherwise the requested
> bits OR together and the kernel reads them independently, the way
> kernel.numa_balancing reads them, so a combined NORMAL|TIERING engages
> both modes. A DISABLED request only speaks for the cgroup's tasks,
> never for its memory, which follows the remaining requests of its
> ancestors.
>
> The cost of the additive combination is that an ancestor cannot cap
> tiering short of a full opt-out: a descendant's TIERING request
> re-engages promotion for its own memory, and promotion is the mode that
> consumes the shared fast tier.
I am not sure that this matches the usual cgroup hierarchy semantics.
If promotion consumes the shared fast tier, why is a descendant allowed
to re-enable TIERING when an ancestor cannot cap it short of a full
opt-out?
Thanks,
Zhe
>
> The readback contract is worth spelling out: bpf_numab_get_mode()
> returns the combined request of the cgroup and its ancestors, and the
> kernel reads it the same way it reads a single request, each bit
> independently as kernel.numa_balancing does, so a combined
> NORMAL|TIERING engages both modes. When any cgroup in the chain makes a
> request, the value read back is the mode in effect for the cgroup's tasks;
> when none does, the readback is NUMAB_FOLLOW_SYSTEM (-1) and the sysctl
> decides. The answer speaks for the cgroup's tasks only: its memory follows
> the remaining requests of its chain when it opts out, and that folio-side
> view is not exposed by the kfuncs. These are deliberate simplifications;
> both can be revisited if callers turn out to need them.
>
> The sysctl's own documentation is untouched; the override is documented
> where it lives, in the CONFIG_BPF_NUMAB Kconfig help and the kfunc docs.
>
> The override was measured with schbench, 384 workers, on a two-node
> 384-core machine. Whatever kernel.numa_balancing is set to, a cgroup
> request puts the cgroup at the throughput of the equivalent
> system-wide setting, within a fraction of a percent: the override
> itself costs nothing measurable, performance follows the effective
> state alone. The two states themselves differ by less than a percent
> under this load.
>
> Changes
> =======
>
> RFC v2->RFC v3:
> - The struct_ops interface is replaced by two kfuncs, following
> Tejun's suggestion.
> - Improve on the function naming and simplify the code (David)
>
> RFC v2: https://lwn.net/Articles/1099962/
>
> RFC v1->RFC v2:
> v1 keyed the hook on the memory cgroup and temporarily embedded the cgroup
> id into the struct-ops value, because the cgroup struct_ops integration was
> still under development. v2 attaches through the cgroup struct_ops support
> that has since landed in bpf-next, keys the task surface on the task's
> cgroup and the memory surface on the folio's memcg, and adds the
> memory-tiering mode alongside enable and disable.
>
> RFC v1: https://lwn.net/Articles/1054030/
>
> Yafang Shao (5):
> sched: fix stale get_pref_llc() stub for !CONFIG_SCHED_CACHE
> sched: use static_branch_likely() for the NUMA balancing tick check
> sched: add helpers for numa balancing
> sched: add BPF-based per-cgroup NUMA balancing mode selection
> selftests/bpf: add tests for the numab kfuncs
>
> include/linux/cgroup-defs.h | 10 +
> include/linux/sched/numa_balancing.h | 149 ++++++++++++
> init/Kconfig | 20 ++
> kernel/cgroup/cgroup.c | 14 ++
> kernel/sched/bpf_numab.c | 195 +++++++++++++++
> kernel/sched/build_policy.c | 4 +
> kernel/sched/fair.c | 33 +--
> kernel/sched/sched.h | 1 -
> mm/memory-tiers.c | 9 +-
> mm/mempolicy.c | 3 +-
> mm/migrate.c | 7 +-
> mm/vmscan.c | 6 +-
> .../selftests/bpf/prog_tests/bpf_numab.c | 227 ++++++++++++++++++
> tools/testing/selftests/bpf/progs/bpf_numab.c | 32 +++
> 14 files changed, 681 insertions(+), 29 deletions(-)
> create mode 100644 kernel/sched/bpf_numab.c
> create mode 100644 tools/testing/selftests/bpf/prog_tests/bpf_numab.c
> create mode 100644 tools/testing/selftests/bpf/progs/bpf_numab.c
prev parent reply other threads:[~2026-10-23 6:32 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 6:41 Yafang Shao
2026-10-19 6:41 ` [RFC PATCH v3 bpf-next 1/5] sched: fix stale get_pref_llc() stub for !CONFIG_SCHED_CACHE Yafang Shao
2026-10-21 2:23 ` Gregory Price (Meta)
2026-10-21 5:46 ` Yafang Shao
2026-10-21 2:40 ` Chen Yu
2026-10-21 20:40 ` Tim Chen
2026-10-19 6:41 ` [RFC PATCH v3 bpf-next 2/5] sched: use static_branch_likely() for the NUMA balancing tick check Yafang Shao
2026-10-21 2:26 ` Gregory Price (Meta)
2026-10-19 6:41 ` [RFC PATCH v3 bpf-next 3/5] sched: add helpers for numa balancing Yafang Shao
2026-10-19 7:14 ` bot+bpf-ci
2026-10-19 6:41 ` [RFC PATCH v3 bpf-next 4/5] sched: add BPF-based per-cgroup NUMA balancing mode selection Yafang Shao
2026-10-19 7:24 ` bot+bpf-ci
2026-10-19 6:41 ` [RFC PATCH v3 bpf-next 5/5] selftests/bpf: add tests for the numab kfuncs Yafang Shao
2026-10-20 16:54 ` [RFC PATCH v3 bpf-next 0/5] BPF-based per-cgroup NUMA balancing mode selection Tejun Heo
2026-10-23 6:32 ` Li Zhe [this message]
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=f68e7f9e-6037-4087-b7cd-a17ea4dba279@bytedance.com \
--to=lizhe.67@bytedance.com \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=cgroups@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=david@kernel.org \
--cc=eddyz87@gmail.com \
--cc=gourry@gourry.net \
--cc=hannes@cmpxchg.org \
--cc=juri.lelli@redhat.com \
--cc=laoar.shao@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=memxor@gmail.com \
--cc=mingo@redhat.com \
--cc=mkoutny@suse.com \
--cc=peterz@infradead.org \
--cc=roman.gushchin@linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=tim.c.chen@linux.intel.com \
--cc=tj@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=yu.c.chen@intel.com \
--cc=zhao1.liu@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®