The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Bharata B Rao <bharata@amd.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: <linux-kernel@vger.kernel.org>, <linux-mm@kvack.org>,
	<Jonathan.Cameron@huawei.com>, <dave.hansen@intel.com>,
	<gourry@gourry.net>, <mgorman@techsingularity.net>,
	<mingo@redhat.com>, <peterz@infradead.org>,
	<raghavendra.kt@amd.com>, <riel@surriel.com>,
	<rientjes@google.com>, <sj@kernel.org>, <weixugc@google.com>,
	<willy@infradead.org>, <ying.huang@linux.alibaba.com>,
	<ziy@nvidia.com>, <dave@stgolabs.net>, <nifan.cxl@gmail.com>,
	<xuezhengchu@huawei.com>, <yiannis@zptcorp.com>,
	<david@kernel.org>, <byungchul@sk.com>, <kinseyho@google.com>,
	<joshua.hahnjy@gmail.com>, <yuanchu@google.com>,
	<balbirs@nvidia.com>, <alok.rathore@samsung.com>,
	<shivankg@amd.com>, <donettom@linux.ibm.com>
Subject: Re: [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure
Date: Thu, 6 Aug 2026 11:19:22 +0530	[thread overview]
Message-ID: <d2a84790-16a0-488c-854a-e135feb2f65c@amd.com> (raw)
In-Reply-To: <20260728111401.b6d674baf8e56a27c55e0c52@linux-foundation.org>

On 28-Jul-26 11:44 PM, Andrew Morton wrote:
> On Tue, 28 Jul 2026 11:13:48 +0530 Bharata B Rao <bharata@amd.com> wrote:
> 
>> This patchset introduces pghot, a subsystem for hot page tracking and
>> promotion.
> 
> Can DAMON be used to do this sort of thing adequately?

Hi SJ,

I started comparing hot page detection and promotion aspects of DAMON
and pghot through benchmark runs. Here is the first set of results from
pointer chase workload.

Since I wasn't very familiar with DAMON tunables and settings, I let the
AI to chose some default followed by other combinations. The test harness
is developed and run by AI. Request you to go through this and let me know
you feedback about the combinations and configurations tried here. Based on
that I can adapt the settings for the future runs.

======================================================================
DAMON vs pghot: hot-page detection and promotion, measured
(single-threaded and 64-thread workloads)
======================================================================

Summary
-------
This note compares DAMON and pghot on how well each detects a 16 GB hot set
on a slow-tier node and promotes it to the fast tier, using the same
pointer-chase workload on a 3-tier NUMA machine.  Here DAMON refers to the
in-kernel access sampling with the DAMOS migrate_hot/migrate_cold actions,
and pghot refers to per-PFN hotness tracking with the kmigrated promotion
thread.  All runs are from one uniform harness with the same metric set.

In short, pghot promotes exactly the hot set with only a couple of sysctls,
and it behaves the same way irrespective of the thread count.  DAMON can
reach a comparable steady-state accuracy, but only with workload-specific
tuning, and (to bound the fast-tier residency) only with a full
bidirectional promote-plus-demote setup.  Even then, it reaches the right
amount only after first over-promoting and then settling back down.  Two
further pitfalls are worth noting: one seemingly reasonable tuning promoted
nothing at all, and the promote-only configurations over-promote heavily.
The difference largely reflects region-granular sampling on the DAMON side
versus per-page tracking on the pghot side.

Test setup
----------
Machine  : 3 NUMA nodes.  node0,node1 = DRAM w/ CPUs, 256 GB each (top
           tier).  node2 = CPU-less slow tier, 256 GB, SLIT distance 50
           (asymmetric 255).  phys 0x8100000000..0xc100000000.
Kernels  : base  = 7.2.0-rc6 (DAMON; NUMAB tiering)
           pghot = 7.2.0-rc6 + pghot v8+
Workload : pointer chase (dependent loads, latency bound) over a 64 GB anon
           buffer; 16 GB hot subset, rest cold.
           Single-threaded: one thread chases the whole 16 GB.
           Multi-threaded: the buffer is split into 64 chunks of 1 GB, each
           thread chasing its own 256 MB hot sub-region (16 GB hot total
           across 64 CPUs).
           Timed phase = 240 s.
Placement: buffer relocated to node2 via move_pages()
           Task pinned to node0 CPUs, Target = node0.

Legend
------
lat   : mean access latency, ns/access, shown first->steady (last 25%).
conv  : time to within 10% of steady latency (s).  '-' = never / flat.
node0 : fast-tier resident of the workload at end (GB).  Hot set = 16 GB.
over  : over-promotion relative to the 16 GB hot set.
regs  : DAMON monitoring regions actually created, measured via the
        damon_aggregated tracepoint (DAMON runs only).
sample/aggr  : DAMON sampling interval / aggregation interval (Table B).
acc/reg/filt : DAMON min_nr_accesses / max_regions / YOUNG ops-filter.
thr/NB       : pghot_freq_threshold / kernel.numa_balancing.
Note  : DAMON promotion is counted in pgmigrate_success (and the scheme's
        sz_applied); pghot promotion in pgpromote_success and
        pghot_recorded_*.  So placement (numastat) and latency are used for
        the cross-mechanism comparison.  pgdemote_kswapd/pgdemote_direct are
        0 in every run (no reclaim-path demotion).

======================================================================
PART 1 - SINGLE-THREADED  (64 GB total / 16 GB hot)
======================================================================
(base-kernel baseline steady latency 278 ns; pghot-kernel baseline 295 ns)

Table A. Headline: best of each mechanism
-----------------------------------------
Mechanism                          lat        conv  node0  over
                                   (ns)       (s)   (GB)   (%)
---------------------------------  ---------  ----  -----  ----
baseline, no promotion              320->278     -    0.0     -
DAMON promote-only best (row D0)    290->133    33   22.4   +40
DAMON bidirectional     (row D5)    299->138    47   15.3    -4
pghot, hint-fault source (row P1)   166->129    16   16.0     0

Table B. DAMON tuning sweep (base kernel)
-----------------------------------------
id  sample/aggr  acc  reg      filt  lat       conv node0  over  regs
                                     (ns)      (s)  (GB)   (%)
--  -----------  ---  -------  ----  --------  ---- -----  ----  ----
D0  5ms/100ms     1     1,000  no    290->133    33  22.4   +40    12
D1  1ms/ 20ms     2   100,000  yes   311->279     -   0.0   n/a    14
D2  1ms/ 20ms     2 4,000,000  yes   325->280     -   0.0   n/a    13
D3  5ms/100ms     1   100,000  yes   298->123    85  34.4  +115    13
D4  5ms/100ms     1 4,000,000  yes   315->136    96  27.0   +69    14
D5  5ms/100ms     1   100,000  yes   299->138    47  15.3    -4    14  <-bidir

Notes on Table B:
- D0/D3/D4 show that raising max_regions does NOT reduce over-promotion; the
  over-promotion is high and varies run-to-run (+40 / +115 / +69) with no
  trend from the cap.  The measured region count stays ~12-14 in every case
  (see conclusion 3).
- D1/D2 (1 ms / 20 ms window, min_nr_accesses=2) promote nothing at all.
- D5 is bidirectional (promote + a migrate_cold demote scheme on a second
  kdamond over node0).  It ends at 15.3 GB (about the hot set) but only after
  first over-promoting and then demoting the excess.
- kdamond CPU over the 240 s run: D0 7 s, D1/D2 2 s, D3 12 s, D4 9 s, D5 10 s.

Table C. pghot hint-fault source (pghot kernel)
-----------------------------------------------
id  source (mask)         thr NB  lat       conv node0 over
                                  (ns)      (s)  (GB)  (%)
--  --------------------  --- --  --------  ---- ----- ----
P1  hint-fault (0x1)       1   2  166->129    16  16.0    0
P2  hint-fault (0x1)       2   2  388->129    85  16.0    0

vmstat deltas (pghot runs):
- P1 pgpromote_success=1,195,791 (*partial - see below).
- P2 pgpromote_success=4,194,304 (=16 GB exactly),
     pghot_recorded_hintfaults=5,307,760, numa_hint_faults=5,307,760.
* P1 (thr=1) promotes so quickly that most of it happens during the load
  phase, before the vmstat baseline snapshot, so its delta is partial;
  placement (16 GB exact) is the reliable figure.

======================================================================
PART 2 - MULTITHREADED  (64 threads, 64 GB / 16 GB hot)
======================================================================
(base-kernel baseline steady latency 251 ns; pghot-kernel baseline 282 ns)

Here latency does not track placement linearly, so it does not rank the
configs on its own: partial promotion can yield most of the latency gain,
and the two baselines differ by kernel.  The mechanism was not measured
(bandwidth and/or working-set/TLB effects are both plausible), so placement
is used as the accuracy metric.

Table D. Multithreaded results
------------------------------
id  config                  kern   lat  node0  over    regs
                                   (ns) (GB)
--  ----------------------  -----  ---  -----  -----  ------
M0  baseline                 base   251   0.0     -        -
M1  DAMON promo-only 1k      base   124  63.4  +296%     351
M2  DAMON promo-only 100k+y  base   120  61.3  +283%      52
M3  DAMON bidir 1k           base   124  31.1   +95%     588
M4  DAMON bidir 100k+y       base   136  17.1    +7%  21,101
M5  pghot hintfault thr1     pghot  129  16.0     0%       -

Notes on Table D:
- Promotion (vmstat): M1 pgmig 14.2M, M2 15.2M, M3 14.9M, M4 18.4M;
  M5 pgpromote_success 4,112,464 (pghot_recorded_hintfaults 2,490,368).
- M1/M2 promote-only over-promote to nearly the whole 64 GB buffer.  With no
  demotion, one-way promotion plus region-boundary false positives keep
  accumulating over the run.
- M3/M4 add a migrate_cold demote scheme (a second kdamond over node0).  M4
  (fine regions) ends at 17.1 GB (about the hot set) after a mid-run
  overshoot and a long settle.
- Region counts are much higher than single-threaded, likely because the 64
  per-thread hot chunks create access-rate gradients that DAMON splits on.
  M4 reached 21,101 regions and consequently used 146 s of kdamond CPU over
  the run (vs 17-25 s for M1-M3); that is still far coarser than page size
  and it still over-promotes (+7%).
- M5 behaves the same as the single-threaded pghot run (not sensitive to the
  thread count).

Table E. DAMON migration & demotion counters (all DAMON runs)
-------------------------------------------------------------
pgdemote_kswapd and pgdemote_direct are 0 in every DAMON run: DAMON's
demotion (the bidirectional migrate_cold scheme) is explicit migration,
counted in pgmigrate_success and the scheme's sz_applied, not reclaim-path
demotion.  The reclaim counters would move only under fast-tier memory
pressure (the overcommit case, left to a separate test).

run               pgmigrate_success  pgdem_kswapd  pgdem_direct  demote GB
----------------  -----------------  ------------  ------------  ---------
st-d0 (po,1k)             6,293,366             0             0          -
st-d1 (nil)                      0             0             0          -
st-d2 (nil)                      0             0             0          -
st-d3 (po,100k)          8,573,820             0             0          -
st-d4 (po,4M)            7,081,247             0             0          -
st-d5 (bidir)            8,607,955             0             0        9.6
mt-d0 (po,1k)           14,182,546             0             0          -
mt-fine (po,100k)       15,160,909             0             0          -
mt-bidir-coarse         14,889,977             0             0       13.7
mt-bidir-fine           18,356,299             0             0       26.5
(po = promote-only; demote GB = demote scheme sz_applied, bidir only.  For
 promote-only, pgmigrate_success is the promotion count; for bidir it is
 promotion + demotion combined.  E.g. mt-bidir-fine promoted 43.6 GB and
 demoted 26.5 GB to net-place 17.1 GB.)

======================================================================
Conclusions
======================================================================

1. DAMON needs considerably more, and less obvious, tuning than pghot.
   A seemingly reasonable "faster and stricter" DAMON (1 ms sample, 20 ms
   aggr, min_nr_accesses=2) promoted nothing at all (D1/D2).  This is
   consistent with the per-page reuse distance (~1 s for the single-threaded
   chase) far exceeding the 20 ms aggregation window, so few regions reach 2
   accesses within a window and DAMON treats them as cold.  Working operation
   needed a 100 ms window and min_nr_accesses=1.
   pghot worked in every configuration with numa_balancing=2 (+ optional
   pghot_freq_threshold).

2. Region sampling over-promotes; per-PFN tracking is exact.
   Single-threaded, every promote-only DAMON config over-promoted, by a
   variable amount with no trend from the region cap (D0/1k=+40%,
   D3/100k=+115%, D4/4M=+69%); pghot placed exactly 16 GB in every
   hint-fault run.  Adding a demote scheme (D5, bidirectional) brings
   single-thread DAMON to about 16 GB (15.3 GB), but it gets there by
   promoting too much and then demoting the excess.  Multithreaded,
   promote-only DAMON over-promotes to ~62-63 GB (+283-296%); only the
   bidirectional fine config bounds it near the hot set (17.1 GB, +7%).

3. Setting the region size to the page size does not close the gap in
   practice.  I measured the number of monitoring regions DAMON actually
   created, using the damon_aggregated tracepoint.  Single-threaded, DAMON
   created only about 12-15 regions in every case (max_regions = 1,000 /
   100,000 / 4,000,000), so the cap is never the binding constraint, and
   kdamond used only 2-12 s of CPU.  Multithreaded, DAMON splits more - 52 to
   588 regions for most configs, and 21,101 for the bidirectional-fine run
   (likely because the per-thread hot chunks create access-rate gradients) -
   but that is still far coarser than page size, and it cost 146 s of kdamond
   CPU while still over-promoting (+7%).  Reaching page-sized regions over the
   256 GB slow tier would need about 67 M regions (the 16 GB hot set alone
   ~4 M), i.e. around 4 GB of region structures walked by a single kdamond
   every aggregation.  DAMON does not create anywhere near that many, and the
   rising kdamond CPU (146 s at 21,101 regions versus 2-25 s otherwise) is
   consistent with the cost of pushing toward that count.

4. Using many threads helps DAMON's detection speed but not its accuracy.
   The higher access density lets DAMON detect quickly (latency converges in
   ~10-15 s vs 33-96 s single-threaded).  But promote-only still
   over-promotes to nearly the whole buffer, and bounding the residency still
   requires the bidirectional promote-plus-demote design.  Even then M4
   reaches 17.1 GB only after an overshoot and a long settle, with heavy
   churn (pgmigrate_success 18.4 M, far more than the 4 M pages of the hot
   set) and 146 s of kdamond CPU.  pghot hint-fault places exactly 16 GB with
   the same behaviour as single-threaded, i.e. it is not sensitive to the
   thread count.

Overall, pghot provides exact, prompt promotion with essentially no tuning,
at the per-page granularity that its sources give it, and it is not
sensitive to the thread count.  DAMON can approach the same steady-state
accuracy, but only with workload-specific tuning and a full bidirectional
setup; it can easily be mis-tuned into doing nothing, promote-only
over-promotes heavily, it cannot in practice be pushed down to page-sized
regions, and in the multithreaded case it reaches the right answer only after
an over-promote-and-settle transient with substantial migration churn and
kdamond CPU.

======================================================================
Methodology caveats
======================================================================
- Latency is the primary metric for this pointer-chase workload, but in the
  multithreaded case it does not track placement linearly (baselines differ
  by kernel; partial promotion can lower the latency out of proportion to
  how much was promoted).  This was not root-caused - bandwidth and/or
  working-set/TLB effects are both plausible and were not measured - so it
  must be read alongside placement (numastat).
- Over-promotion figures vary by several GB run-to-run; the conclusions are
  stable but the exact GB values are approximate.
- DAMON and pghot increment different vmstat counters; the cross-mechanism
  comparison relies on placement and latency, which are mechanism-independent.
- vmstat counters are snapshotted around the 240 s timed phase (after the
  move_pages load phase), and hence exclude the relocation migrations.
- The overcommit case (hot set larger than the fast-tier capacity, which
  would exercise demotion under pressure) is left to a separate test.

Regards,
Bharata.

  parent reply	other threads:[~2026-08-06  5:49 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28  5:43 [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 1/8] mm: migrate: Allow misplaced migration without VMA Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 2/8] mm: migrate: Add promote_misplaced_memcg_folios() Bharata B Rao
2026-07-30  6:34   ` Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 3/8] mm: Hot page tracking and promotion - pghot Bharata B Rao
2026-07-31 16:14   ` Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 4/8] mm: pghot: Precision mode for pghot Bharata B Rao
2026-07-31 16:27   ` Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 5/8] mm: sched: move NUMA balancing tiering promotion to pghot Bharata B Rao
2026-08-03  8:23   ` Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 6/8] x86/ibs: Move IBS caps definitions into its own header Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 7/8] x86/mm/ibs: In-kernel driver for AMD IBS Memory Profiler Bharata B Rao
2026-08-04  5:00   ` Bharata B Rao
2026-07-28  5:43 ` [PATCH v8 8/8] x86/mm/ibs: Add runtime controls for IBS memprofiler Bharata B Rao
2026-08-04  5:20   ` Bharata B Rao
2026-07-28  5:55 ` [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure - microbenchmark numbers Bharata B Rao
2026-07-28  5:59 ` [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure - NAS BT Bharata B Rao
2026-07-28  6:02 ` [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure - Graph500 Bharata B Rao
2026-07-28  6:05 ` [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure - redis-memtier Bharata B Rao
2026-07-28  6:17 ` [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure - llama-bench Bharata B Rao
2026-07-28 18:14 ` [PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure Andrew Morton
2026-07-28 18:24   ` Matthew Wilcox
2026-07-28 18:57     ` Gregory Price
2026-07-28 19:20       ` David Hildenbrand (Arm)
2026-07-28 19:59         ` Gregory Price
2026-07-29 11:45         ` Bharata B Rao
2026-07-29  9:35   ` Bharata B Rao
2026-07-29 13:54     ` SJ Park
2026-08-04  1:23       ` SJ Park
2026-08-06  5:49   ` Bharata B Rao [this message]
2026-08-06 13:44     ` SJ Park

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=d2a84790-16a0-488c-854a-e135feb2f65c@amd.com \
    --to=bharata@amd.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=akpm@linux-foundation.org \
    --cc=alok.rathore@samsung.com \
    --cc=balbirs@nvidia.com \
    --cc=byungchul@sk.com \
    --cc=dave.hansen@intel.com \
    --cc=dave@stgolabs.net \
    --cc=david@kernel.org \
    --cc=donettom@linux.ibm.com \
    --cc=gourry@gourry.net \
    --cc=joshua.hahnjy@gmail.com \
    --cc=kinseyho@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@techsingularity.net \
    --cc=mingo@redhat.com \
    --cc=nifan.cxl@gmail.com \
    --cc=peterz@infradead.org \
    --cc=raghavendra.kt@amd.com \
    --cc=riel@surriel.com \
    --cc=rientjes@google.com \
    --cc=shivankg@amd.com \
    --cc=sj@kernel.org \
    --cc=weixugc@google.com \
    --cc=willy@infradead.org \
    --cc=xuezhengchu@huawei.com \
    --cc=yiannis@zptcorp.com \
    --cc=ying.huang@linux.alibaba.com \
    --cc=yuanchu@google.com \
    --cc=ziy@nvidia.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