From: Bharata B Rao <bharata@amd.com>
To: <linux-kernel@vger.kernel.org>, <linux-mm@kvack.org>
Cc: <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>,
<akpm@linux-foundation.org>, <david@redhat.com>,
<byungchul@sk.com>, <kinseyho@google.com>,
<joshua.hahnjy@gmail.com>, <yuanchu@google.com>,
<balbirs@nvidia.com>, <alok.rathore@samsung.com>,
<shivankg@amd.com>, Bharata B Rao <bharata@amd.com>
Subject: [RFC PATCH v4 4/9] x86: ibs: In-kernel IBS driver for memory access profiling
Date: Sat, 6 Dec 2025 15:44:18 +0530 [thread overview]
Message-ID: <20251206101423.5004-5-bharata@amd.com> (raw)
In-Reply-To: <20251206101423.5004-1-bharata@amd.com>
Use IBS (Instruction Based Sampling) feature present
in AMD processors for memory access tracking. The access
information obtained from IBS via NMI is fed to pghot
sub-system for futher action.
In addition to many other information related to the memory
access, IBS provides physical (and virtual) address of the access
and indicates if the access came from slower tier. Only memory
accesses originating from slower tiers are further acted upon
by this driver.
The samples are initially accumulated in percpu buffers which
are flushed to pghot hot page tracking mechanism using irq_work.
TODO: Many counters are added to vmstat just as debugging aid
for now.
About IBS
---------
IBS can be programmed to provide data about instruction
execution periodically. This is done by programming a desired
sample count (number of ops) in a control register. When the
programmed number of ops are dispatched, a micro-op gets tagged,
various information about the tagged micro-op's execution is
populated in IBS execution MSRs and an interrupt is raised.
While IBS provides a lot of data for each sample, for the
purpose of memory access profiling, we are interested in
linear and physical address of the memory access that reached
DRAM. Recent AMD processors provide further filtering where
it is possible to limit the sampling to those ops that had
an L3 miss which greately reduces the non-useful samples.
While IBS provides capability to sample instruction fetch
and execution, only IBS execution sampling is used here
to collect data about memory accesses that occur during
the instruction execution.
More information about IBS is available in Sec 13.3 of
AMD64 Architecture Programmer's Manual, Volume 2:System
Programming which is present at:
https://bugzilla.kernel.org/attachment.cgi?id=288923
Information about MSRs used for programming IBS can be
found in Sec 2.1.14.4 of PPR Vol 1 for AMD Family 19h
Model 11h B1 which is currently present at:
https://www.amd.com/system/files/TechDocs/55901_0.25.zip
Signed-off-by: Bharata B Rao <bharata@amd.com>
---
arch/x86/events/amd/ibs.c | 10 +
arch/x86/include/asm/msr-index.h | 16 ++
arch/x86/mm/Makefile | 1 +
arch/x86/mm/ibs.c | 316 +++++++++++++++++++++++++++++++
include/linux/pghot.h | 6 +
include/linux/vm_event_item.h | 19 ++
mm/Kconfig | 13 ++
mm/vmstat.c | 19 ++
8 files changed, 400 insertions(+)
create mode 100644 arch/x86/mm/ibs.c
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 112f43b23ebf..e387c18c91f8 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -13,6 +13,7 @@
#include <linux/ptrace.h>
#include <linux/syscore_ops.h>
#include <linux/sched/clock.h>
+#include <linux/pghot.h>
#include <asm/apic.h>
#include <asm/msr.h>
@@ -1756,6 +1757,15 @@ static __init int amd_ibs_init(void)
{
u32 caps;
+ /*
+ * TODO: Find a clean way to disable perf IBS so that IBS
+ * can be used for memory access profiling.
+ */
+ if (hwmem_access_profiler_inuse()) {
+ pr_info("IBS isn't available for perf use\n");
+ return 0;
+ }
+
caps = __get_ibs_caps();
if (!caps)
return -ENODEV; /* ibs not supported by the cpu */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 9e1720d73244..59657bd768c9 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -760,6 +760,22 @@
/* AMD Last Branch Record MSRs */
#define MSR_AMD64_LBR_SELECT 0xc000010e
+/* AMD IBS MSR bits */
+#define MSR_AMD64_IBSOPDATA2_DATASRC 0x7
+#define MSR_AMD64_IBSOPDATA2_DATASRC_LCL_CACHE 0x1
+#define MSR_AMD64_IBSOPDATA2_DATASRC_PEER_CACHE_NEAR 0x2
+#define MSR_AMD64_IBSOPDATA2_DATASRC_DRAM 0x3
+#define MSR_AMD64_IBSOPDATA2_DATASRC_FAR_CCX_CACHE 0x5
+#define MSR_AMD64_IBSOPDATA2_DATASRC_EXT_MEM 0x8
+#define MSR_AMD64_IBSOPDATA2_RMTNODE 0x10
+
+#define MSR_AMD64_IBSOPDATA3_LDOP BIT_ULL(0)
+#define MSR_AMD64_IBSOPDATA3_STOP BIT_ULL(1)
+#define MSR_AMD64_IBSOPDATA3_DCMISS BIT_ULL(7)
+#define MSR_AMD64_IBSOPDATA3_LADDR_VALID BIT_ULL(17)
+#define MSR_AMD64_IBSOPDATA3_PADDR_VALID BIT_ULL(18)
+#define MSR_AMD64_IBSOPDATA3_L2MISS BIT_ULL(20)
+
/* Zen4 */
#define MSR_ZEN4_BP_CFG 0xc001102e
#define MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT 4
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 5b9908f13dcf..361a456582e9 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_X86_MEM_ENCRYPT) += mem_encrypt.o
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_amd.o
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_boot.o
+obj-$(CONFIG_HWMEM_PROFILER) += ibs.o
diff --git a/arch/x86/mm/ibs.c b/arch/x86/mm/ibs.c
new file mode 100644
index 000000000000..946f3a82ca11
--- /dev/null
+++ b/arch/x86/mm/ibs.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/init.h>
+#include <linux/pghot.h>
+#include <linux/percpu.h>
+#include <linux/workqueue.h>
+#include <linux/irq_work.h>
+
+#include <asm/nmi.h>
+#include <asm/perf_event.h> /* TODO: Move defns like IBS_OP_ENABLE into non-perf header */
+#include <asm/apic.h>
+
+bool hwmem_access_profiling;
+
+static u64 ibs_config __read_mostly;
+static u32 ibs_caps;
+
+#define IBS_NR_SAMPLES 150
+
+/*
+ * Basic access info captured for each memory access.
+ */
+struct ibs_sample {
+ unsigned long pfn;
+ unsigned long time; /* jiffies when accessed */
+ int nid; /* Accessing node ID, if known */
+};
+
+/*
+ * Percpu buffer of access samples. Samples are accumulated here
+ * before pushing them to pghot sub-system for further action.
+ */
+struct ibs_sample_pcpu {
+ struct ibs_sample samples[IBS_NR_SAMPLES];
+ int head, tail;
+};
+
+struct ibs_sample_pcpu __percpu *ibs_s;
+
+/*
+ * The workqueue for pushing the percpu access samples to pghot sub-system.
+ */
+static struct work_struct ibs_work;
+static struct irq_work ibs_irq_work;
+
+bool hwmem_access_profiler_inuse(void)
+{
+ return hwmem_access_profiling;
+}
+
+/*
+ * Record the IBS-reported access sample in percpu buffer.
+ * Called from IBS NMI handler.
+ */
+static int ibs_push_sample(unsigned long pfn, int nid, unsigned long time)
+{
+ struct ibs_sample_pcpu *ibs_pcpu = raw_cpu_ptr(ibs_s);
+ int next = ibs_pcpu->head + 1;
+
+ if (next >= IBS_NR_SAMPLES)
+ next = 0;
+
+ if (next == ibs_pcpu->tail)
+ return 0;
+
+ ibs_pcpu->samples[ibs_pcpu->head].pfn = pfn;
+ ibs_pcpu->samples[ibs_pcpu->head].time = time;
+ ibs_pcpu->head = next;
+ return 1;
+}
+
+static int ibs_pop_sample(struct ibs_sample *s)
+{
+ struct ibs_sample_pcpu *ibs_pcpu = raw_cpu_ptr(ibs_s);
+
+ int next = ibs_pcpu->tail + 1;
+
+ if (ibs_pcpu->head == ibs_pcpu->tail)
+ return 0;
+
+ if (next >= IBS_NR_SAMPLES)
+ next = 0;
+
+ *s = ibs_pcpu->samples[ibs_pcpu->tail];
+ ibs_pcpu->tail = next;
+ return 1;
+}
+
+/*
+ * Remove access samples from percpu buffer and send them
+ * to pghot sub-system for further action.
+ */
+static void ibs_work_handler(struct work_struct *work)
+{
+ struct ibs_sample s;
+
+ while (ibs_pop_sample(&s))
+ pghot_record_access(s.pfn, s.nid, PGHOT_HW_HINTS, s.time);
+}
+
+static void ibs_irq_handler(struct irq_work *i)
+{
+ schedule_work_on(smp_processor_id(), &ibs_work);
+}
+
+/*
+ * IBS NMI handler: Process the memory access info reported by IBS.
+ *
+ * Reads the MSRs to collect all the information about the reported
+ * memory access, validates the access, stores the valid sample and
+ * schedules the work on this CPU to further process the sample.
+ */
+static int ibs_overflow_handler(unsigned int cmd, struct pt_regs *regs)
+{
+ struct mm_struct *mm = current->mm;
+ u64 ops_ctl, ops_data3, ops_data2;
+ u64 laddr = -1, paddr = -1;
+ u64 data_src, rmt_node;
+ struct page *page;
+ unsigned long pfn;
+
+ rdmsrl(MSR_AMD64_IBSOPCTL, ops_ctl);
+
+ /*
+ * When IBS sampling period is reprogrammed via read-modify-update
+ * of MSR_AMD64_IBSOPCTL, overflow NMIs could be generated with
+ * IBS_OP_ENABLE not set. For such cases, return as HANDLED.
+ *
+ * With this, the handler will say "handled" for all NMIs that
+ * aren't related to this NMI. This stems from the limitation of
+ * having both status and control bits in one MSR.
+ */
+ if (!(ops_ctl & IBS_OP_VAL))
+ goto handled;
+
+ wrmsrl(MSR_AMD64_IBSOPCTL, ops_ctl & ~IBS_OP_VAL);
+
+ count_vm_event(HWHINT_NR_EVENTS);
+
+ if (!user_mode(regs)) {
+ count_vm_event(HWHINT_KERNEL);
+ goto handled;
+ }
+
+ if (!mm) {
+ count_vm_event(HWHINT_KTHREAD);
+ goto handled;
+ }
+
+ rdmsrl(MSR_AMD64_IBSOPDATA3, ops_data3);
+
+ /* Load/Store ops only */
+ /* TODO: DataSrc isn't valid for stores, so filter out stores? */
+ if (!(ops_data3 & (MSR_AMD64_IBSOPDATA3_LDOP |
+ MSR_AMD64_IBSOPDATA3_STOP))) {
+ count_vm_event(HWHINT_NON_LOAD_STORES);
+ goto handled;
+ }
+
+ /* Discard the sample if it was L1 or L2 hit */
+ if (!(ops_data3 & (MSR_AMD64_IBSOPDATA3_DCMISS |
+ MSR_AMD64_IBSOPDATA3_L2MISS))) {
+ count_vm_event(HWHINT_DC_L2_HITS);
+ goto handled;
+ }
+
+ rdmsrl(MSR_AMD64_IBSOPDATA2, ops_data2);
+ data_src = ops_data2 & MSR_AMD64_IBSOPDATA2_DATASRC;
+ if (ibs_caps & IBS_CAPS_ZEN4)
+ data_src |= ((ops_data2 & 0xC0) >> 3);
+
+ switch (data_src) {
+ case MSR_AMD64_IBSOPDATA2_DATASRC_LCL_CACHE:
+ count_vm_event(HWHINT_LOCAL_L3L1L2);
+ break;
+ case MSR_AMD64_IBSOPDATA2_DATASRC_PEER_CACHE_NEAR:
+ count_vm_event(HWHINT_LOCAL_PEER_CACHE_NEAR);
+ break;
+ case MSR_AMD64_IBSOPDATA2_DATASRC_DRAM:
+ count_vm_event(HWHINT_DRAM_ACCESSES);
+ break;
+ case MSR_AMD64_IBSOPDATA2_DATASRC_EXT_MEM:
+ count_vm_event(HWHINT_CXL_ACCESSES);
+ break;
+ case MSR_AMD64_IBSOPDATA2_DATASRC_FAR_CCX_CACHE:
+ count_vm_event(HWHINT_FAR_CACHE_HITS);
+ break;
+ }
+
+ rmt_node = ops_data2 & MSR_AMD64_IBSOPDATA2_RMTNODE;
+ if (rmt_node)
+ count_vm_event(HWHINT_REMOTE_NODE);
+
+ /* Is linear addr valid? */
+ if (ops_data3 & MSR_AMD64_IBSOPDATA3_LADDR_VALID)
+ rdmsrl(MSR_AMD64_IBSDCLINAD, laddr);
+ else {
+ count_vm_event(HWHINT_LADDR_INVALID);
+ goto handled;
+ }
+
+ /* Discard kernel address accesses */
+ if (laddr & (1UL << 63)) {
+ count_vm_event(HWHINT_KERNEL_ADDR);
+ goto handled;
+ }
+
+ /* Is phys addr valid? */
+ if (ops_data3 & MSR_AMD64_IBSOPDATA3_PADDR_VALID)
+ rdmsrl(MSR_AMD64_IBSDCPHYSAD, paddr);
+ else {
+ count_vm_event(HWHINT_PADDR_INVALID);
+ goto handled;
+ }
+
+ pfn = PHYS_PFN(paddr);
+ page = pfn_to_online_page(pfn);
+ if (!page)
+ goto handled;
+
+ if (!PageLRU(page)) {
+ count_vm_event(HWHINT_NON_LRU);
+ goto handled;
+ }
+
+ if (!ibs_push_sample(pfn, numa_node_id(), jiffies)) {
+ count_vm_event(HWHINT_BUFFER_FULL);
+ goto handled;
+ }
+
+ irq_work_queue(&ibs_irq_work);
+ count_vm_event(HWHINT_USEFUL_SAMPLES);
+
+handled:
+ return NMI_HANDLED;
+}
+
+static inline int get_ibs_lvt_offset(void)
+{
+ u64 val;
+
+ rdmsrl(MSR_AMD64_IBSCTL, val);
+ if (!(val & IBSCTL_LVT_OFFSET_VALID))
+ return -EINVAL;
+
+ return val & IBSCTL_LVT_OFFSET_MASK;
+}
+
+static void setup_APIC_ibs(void)
+{
+ int offset;
+
+ offset = get_ibs_lvt_offset();
+ if (offset < 0)
+ goto failed;
+
+ if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
+ return;
+failed:
+ pr_warn("IBS APIC setup failed on cpu #%d\n",
+ smp_processor_id());
+}
+
+static void clear_APIC_ibs(void)
+{
+ int offset;
+
+ offset = get_ibs_lvt_offset();
+ if (offset >= 0)
+ setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
+}
+
+static int x86_amd_ibs_access_profile_startup(unsigned int cpu)
+{
+ setup_APIC_ibs();
+ return 0;
+}
+
+static int x86_amd_ibs_access_profile_teardown(unsigned int cpu)
+{
+ clear_APIC_ibs();
+ return 0;
+}
+
+static int __init ibs_access_profiling_init(void)
+{
+ if (!boot_cpu_has(X86_FEATURE_IBS)) {
+ pr_info("IBS capability is unavailable for access profiling\n");
+ return 0;
+ }
+
+ ibs_s = alloc_percpu_gfp(struct ibs_sample_pcpu, GFP_KERNEL | __GFP_ZERO);
+ if (!ibs_s)
+ return 0;
+
+ INIT_WORK(&ibs_work, ibs_work_handler);
+ init_irq_work(&ibs_irq_work, ibs_irq_handler);
+
+ /* Uses IBS Op sampling */
+ ibs_config = IBS_OP_CNT_CTL | IBS_OP_ENABLE;
+ ibs_caps = cpuid_eax(IBS_CPUID_FEATURES);
+ if (ibs_caps & IBS_CAPS_ZEN4)
+ ibs_config |= IBS_OP_L3MISSONLY;
+
+ register_nmi_handler(NMI_LOCAL, ibs_overflow_handler, 0, "ibs");
+
+ cpuhp_setup_state(CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
+ "x86/amd/ibs_access_profile:starting",
+ x86_amd_ibs_access_profile_startup,
+ x86_amd_ibs_access_profile_teardown);
+
+ pr_info("IBS setup for memory access profiling\n");
+ return 0;
+}
+
+arch_initcall(ibs_access_profiling_init);
diff --git a/include/linux/pghot.h b/include/linux/pghot.h
index 802240d574a6..6410cb131d3d 100644
--- a/include/linux/pghot.h
+++ b/include/linux/pghot.h
@@ -2,6 +2,12 @@
#ifndef _LINUX_PGHOT_H
#define _LINUX_PGHOT_H
+#ifdef CONFIG_HWMEM_PROFILER
+bool hwmem_access_profiler_inuse(void);
+#else
+static inline bool hwmem_access_profiler_inuse(void) { return false; }
+#endif
+
/* Page hotness temperature sources */
enum pghot_src {
PGHOT_HW_HINTS,
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 5b8fd93b55fd..67efbca9051c 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -193,6 +193,25 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
PGHOT_RECORD_HWHINTS,
PGHOT_RECORD_PGTSCANS,
PGHOT_RECORD_HINTFAULTS,
+#ifdef CONFIG_HWMEM_PROFILER
+ HWHINT_NR_EVENTS,
+ HWHINT_KERNEL,
+ HWHINT_KTHREAD,
+ HWHINT_NON_LOAD_STORES,
+ HWHINT_DC_L2_HITS,
+ HWHINT_LOCAL_L3L1L2,
+ HWHINT_LOCAL_PEER_CACHE_NEAR,
+ HWHINT_FAR_CACHE_HITS,
+ HWHINT_DRAM_ACCESSES,
+ HWHINT_CXL_ACCESSES,
+ HWHINT_REMOTE_NODE,
+ HWHINT_LADDR_INVALID,
+ HWHINT_KERNEL_ADDR,
+ HWHINT_PADDR_INVALID,
+ HWHINT_NON_LRU,
+ HWHINT_BUFFER_FULL,
+ HWHINT_USEFUL_SAMPLES,
+#endif /* CONFIG_HWMEM_PROFILER */
#endif /* CONFIG_PGHOT */
NR_VM_EVENT_ITEMS
};
diff --git a/mm/Kconfig b/mm/Kconfig
index 472975da69e1..6057c96b9cd3 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1390,6 +1390,19 @@ config PGHOT
by various sources. Asynchronous promotion is done by per-node
kernel threads.
+config HWMEM_PROFILER
+ bool "HW based memory access profiling"
+ def_bool n
+ depends on PGHOT
+ depends on X86_64
+ help
+ Some hardware platforms are capable of providing memory access
+ information in direct and actionable manner. Instruction Based
+ Sampling (IBS) present on AMD Zen CPUs in one such example.
+ Memory accesses obtained via such HW based mechanisms are
+ rolled up to PGHOT sub-system for further action like hot page
+ promotion or NUMA Balancing
+
source "mm/damon/Kconfig"
endmenu
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 10745e498e3a..4160476c4ee5 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1501,6 +1501,25 @@ const char * const vmstat_text[] = {
[I(PGHOT_RECORD_HWHINTS)] = "pghot_recorded_hwhints",
[I(PGHOT_RECORD_PGTSCANS)] = "pghot_recorded_pgtscans",
[I(PGHOT_RECORD_HINTFAULTS)] = "pghot_recorded_hintfaults",
+#ifdef CONFIG_HWMEM_PROFILER
+ [I(HWHINT_NR_EVENTS)] = "hwhint_nr_events",
+ [I(HWHINT_KERNEL)] = "hwhint_kernel",
+ [I(HWHINT_KTHREAD)] = "hwhint_kthread",
+ [I(HWHINT_NON_LOAD_STORES)] = "hwhint_non_load_stores",
+ [I(HWHINT_DC_L2_HITS)] = "hwhint_dc_l2_hits",
+ [I(HWHINT_LOCAL_L3L1L2)] = "hwhint_local_l3l1l2",
+ [I(HWHINT_LOCAL_PEER_CACHE_NEAR)] = "hwhint_local_peer_cache_near",
+ [I(HWHINT_FAR_CACHE_HITS)] = "hwhint_far_cache_hits",
+ [I(HWHINT_DRAM_ACCESSES)] = "hwhint_dram_accesses",
+ [I(HWHINT_CXL_ACCESSES)] = "hwhint_cxl_accesses",
+ [I(HWHINT_REMOTE_NODE)] = "hwhint_remote_node",
+ [I(HWHINT_LADDR_INVALID)] = "hwhint_invalid_laddr",
+ [I(HWHINT_KERNEL_ADDR)] = "hwhint_kernel_addr",
+ [I(HWHINT_PADDR_INVALID)] = "hwhint_invalid_paddr",
+ [I(HWHINT_NON_LRU)] = "hwhint_non_lru",
+ [I(HWHINT_BUFFER_FULL)] = "hwhint_buffer_full",
+ [I(HWHINT_USEFUL_SAMPLES)] = "hwhint_useful_samples",
+#endif /* CONFIG_HWMEM_PROFILER */
#endif /* CONFIG_PGHOT */
#undef I
#endif /* CONFIG_VM_EVENT_COUNTERS */
--
2.34.1
next prev parent reply other threads:[~2025-12-06 10:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-06 10:14 [RFC PATCH v4 0/9] mm: Hot page tracking and promotion infrastructure Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 1/9] mm: migrate: Allow misplaced migration without VMA too Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 2/9] migrate: implement migrate_misplaced_folios_batch Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 3/9] mm: Hot page tracking and promotion Bharata B Rao
2025-12-06 10:14 ` Bharata B Rao [this message]
2025-12-06 10:14 ` [RFC PATCH v4 5/9] x86: ibs: Enable IBS profiling for memory accesses Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 6/9] mm: mglru: generalize page table walk Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 7/9] mm: klruscand: use mglru scanning for page promotion Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 8/9] mm: sched: Move hot page promotion from NUMAB=2 to pghot tracking Bharata B Rao
2025-12-06 10:14 ` [RFC PATCH v4 9/9] mm: pghot: Add folio_mark_accessed() as hotness source Bharata B Rao
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=20251206101423.5004-5-bharata@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@redhat.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