| From: Li Zhijian <lizhijian@fujitsu.com> |
| Subject: mm/memory-tier: fix abstract distance calculation overflow |
| Date: Tue, 10 Jun 2025 14:27:51 +0800 |
| |
| In mt_perf_to_adistance(), the calculation of abstract distance (adist) |
| involves multiplying several int values including |
| MEMTIER_ADISTANCE_DRAM. |
| |
| *adist = MEMTIER_ADISTANCE_DRAM * |
| (perf->read_latency + perf->write_latency) / |
| (default_dram_perf.read_latency + default_dram_perf.write_latency) * |
| (default_dram_perf.read_bandwidth + default_dram_perf.write_bandwidth) / |
| (perf->read_bandwidth + perf->write_bandwidth); |
| |
| Since these values can be large, the multiplication may exceed the |
| maximum value of an int (INT_MAX) and overflow (Our platform did), |
| leading to an incorrect adist. |
| |
| User-visible impact: |
| The memory tiering subsystem will misinterpret slow memory (like CXL) |
| as faster than DRAM, causing inappropriate demotion of pages from |
| CXL (slow memory) to DRAM (fast memory). |
| |
| For example, we will see the following demotion chains from the dmesg, where |
| Node0,1 are DRAM, and Node2,3 are CXL node: |
| Demotion targets for Node 0: null |
| Demotion targets for Node 1: null |
| Demotion targets for Node 2: preferred: 0-1, fallback: 0-1 |
| Demotion targets for Node 3: preferred: 0-1, fallback: 0-1 |
| |
| Change MEMTIER_ADISTANCE_DRAM to be a long constant by writing it with |
| the 'L' suffix. This prevents the overflow because the multiplication |
| will then be done in the long type which has a larger range. |
| |
| Link: https://lkml.kernel.org/r/20250611023439.2845785-1-lizhijian@fujitsu.com |
| Link: https://lkml.kernel.org/r/20250610062751.2365436-1-lizhijian@fujitsu.com |
| Fixes: 3718c02dbd4c ("acpi, hmat: calculate abstract distance with HMAT") |
| Signed-off-by: Li Zhijian <lizhijian@fujitsu.com> |
| Reviewed-by: Huang Ying <ying.huang@linux.alibaba.com> |
| Acked-by: Balbir Singh <balbirs@nvidia.com> |
| Reviewed-by: Donet Tom <donettom@linux.ibm.com> |
| Reviewed-by: Oscar Salvador <osalvador@suse.de> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| include/linux/memory-tiers.h | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/include/linux/memory-tiers.h~mm-memory-tier-fix-abstract-distance-calculation-overflow |
| +++ a/include/linux/memory-tiers.h |
| @@ -18,7 +18,7 @@ |
| * adistance value (slightly faster) than default DRAM adistance to be part of |
| * the same memory tier. |
| */ |
| -#define MEMTIER_ADISTANCE_DRAM ((4 * MEMTIER_CHUNK_SIZE) + (MEMTIER_CHUNK_SIZE >> 1)) |
| +#define MEMTIER_ADISTANCE_DRAM ((4L * MEMTIER_CHUNK_SIZE) + (MEMTIER_CHUNK_SIZE >> 1)) |
| |
| struct memory_tier; |
| struct memory_dev_type { |
| _ |