
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICGGS3 CVE: NA -------------------------------- SPE memory access records can be used by NUMA balancing and DAMON for accurate kernel-side memory profiling. However, the current implementation suffers from inaccuracies in kernel-side consumers due to two key issues: 1. The `mem_sampling_record` exposed to kernel consumers is not correctly synchronized with `struct arm_spe_record`. This leads to fields such as physical address, virtual address, or task-related metadata being outdated or inconsistent. 2. In dual-buffer configurations, the function `mm_spe_getbuf_addr()` fails to return the correct `record_base` when the backup buffer is in use. As a result, consumers may fetch stale or invalid sampling data. This patch addresses both problems by: - Explicitly copying all relevant fields from `struct arm_spe_record` into `mem_sampling_record` before it is passed to users. - Updating `mm_spe_getbuf_addr()` to check both active and backup buffer state and return the correct `record_base` accordingly. With this fix, NUMA auto-balancing and DAMON-based sampling can operate on accurate and up-to-date SPE sample data in all buffer modes. Fixs: 5e73787bd539 ("mm/numa: Use mem_sampling framework for NUMA balancing") Signed-off-by: Ze Zuo <zuoze1@huawei.com> --- drivers/arm/mm_monitor/mm_spe.c | 4 ++-- include/linux/mem_sampling.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/arm/mm_monitor/mm_spe.c b/drivers/arm/mm_monitor/mm_spe.c index 3c0438ab54e4..73fa4acdc998 100644 --- a/drivers/arm/mm_monitor/mm_spe.c +++ b/drivers/arm/mm_monitor/mm_spe.c @@ -366,11 +366,11 @@ void mm_spe_decoding(void) arm_spe_decode_buf(spe_buf->cur, spe_buf->size); } -struct mm_spe_buf *mm_spe_getbuf_addr(void) +void *mm_spe_getbuf_addr(void) { struct mm_spe_buf *spe_buf = this_cpu_ptr(&per_cpu_spe_buf); - return spe_buf; + return spe_buf->record_base; } int mm_spe_getnum_record(void) diff --git a/include/linux/mem_sampling.h b/include/linux/mem_sampling.h index 71d098fd3c05..b325c9955d31 100644 --- a/include/linux/mem_sampling.h +++ b/include/linux/mem_sampling.h @@ -49,6 +49,7 @@ struct mem_sampling_record { u64 context_id; u64 boost_spe_addr[8]; u64 rem_addr; + u16 boost_spe_idx; u16 source; }; @@ -57,7 +58,7 @@ struct mem_sampling_ops_struct { void (*sampling_stop)(void); void (*sampling_continue)(void); void (*sampling_decoding)(void); - struct mm_spe_buf* (*mm_spe_getbuf_addr)(void); + void* (*mm_spe_getbuf_addr)(void); int (*mm_spe_getnum_record)(void); }; @@ -83,7 +84,7 @@ void mm_spe_stop(void); void mm_spe_continue(void); void mm_spe_decoding(void); int mm_spe_getnum_record(void); -struct mm_spe_buf *mm_spe_getbuf_addr(void); +void *mm_spe_getbuf_addr(void); int mm_spe_enabled(void); void arm_spe_set_probe_status(int status); #else @@ -93,7 +94,7 @@ static inline void mm_spe_decoding(void) { } static inline void arm_spe_set_probe_status(int status) { } static inline int mm_spe_start(void) { return 0; } static inline int mm_spe_getnum_record(void) { return 0; } -static inline struct mm_spe_buf *mm_spe_getbuf_addr(void) { return NULL; } +static inline void *mm_spe_getbuf_addr(void) { return NULL; } static inline int mm_spe_enabled(void) { return 0; } #endif /* CONFIG_ARM_SPE_MEM_SAMPLING */ -- 2.25.1