hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ID3R2F -------------------------------- FOR_ALL_ZONES macro doesn't define for ZONE_EXTMEM, thus vm_event_states doesn't contain PGALLOC, ALLOCSTALL, and PGSCAN_SKIP slots for ZONE_EXTMEM. As a result, __count_zid_vm_events() counts wrongly. pgalloc_device in /proc/vmstat will show the count of PGALLOC_MOVABLE, for example. Normally, we should add ZONE_EXTMEM in FOR_ALL_ZONES macro to add slots for ZONE_EXTMEM. But it will break kabi. To fix without breaking kabi, skip counting ZONE_EXTMEM items, and offset 1 slot for zones after ZONE_EXTMEM to count in the correct slots. Fixes: 6097ddd1df0a ("mm: add ZONE_EXTMEM for future extension to avoid kabi broken") Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com> --- include/linux/vmstat.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index d783d5a27352..5493c84b0d45 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -131,8 +131,27 @@ static inline void vm_events_fold_cpu(int cpu) #define count_vm_vma_lock_event(x) do {} while (0) #endif +/* + * FOR_ALL_ZONES macro doesn't define for ZONE_EXTMEM, thus + * vm_event_states doesn't contain slots of ZONE_EXTMEM, leading + * to count ZONE_MOVABLE and ZONE_DEVICE items to wrong slots. + * + * To fix without breaking kabi, skip counting ZONE_EXTMEM items, + * and offset 1 slot for zones after ZONE_EXTMEM to count in the + * correct slots. + */ +#ifndef CONFIG_ZONE_EXTMEM #define __count_zid_vm_events(item, zid, delta) \ __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid, delta) +#else +#define __count_zid_vm_events(item, zid, delta) \ + do { \ + if (zid < ZONE_EXTMEM) \ + __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid, delta); \ + else if (zid > ZONE_EXTMEM) \ + __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid - 1, delta); \ + } while (0) +#endif /* * Zone and node-based page accounting with per cpu differentials. -- 2.43.0