From 5f47bdeb07b884cc8be2cc98557fe44b4b73c955 Mon Sep 17 00:00:00 2001 From: Sooyong Suk Date: Tue, 8 Jul 2025 17:47:33 +0900 Subject: [PATCH] ANDROID: mm: add allocated and total pages for GCMA areas For statistical support, let's add allocated and total size of GCMA areas into gcma stats. Bug: 410432482 Change-Id: Ifcae950fb96d11af560a95c85376fcf5156cd35c Signed-off-by: Sooyong Suk --- include/linux/gcma.h | 2 ++ mm/gcma.c | 3 +++ mm/gcma_sysfs.c | 21 +++++++++++++++++++++ mm/gcma_sysfs.h | 3 +++ 4 files changed, 29 insertions(+) diff --git a/include/linux/gcma.h b/include/linux/gcma.h index 831180cd1483..a8aaf158f382 100644 --- a/include/linux/gcma.h +++ b/include/linux/gcma.h @@ -6,11 +6,13 @@ #ifdef CONFIG_GCMA enum gcma_stat_type { + ALLOCATED_PAGE, STORED_PAGE, LOADED_PAGE, EVICTED_PAGE, CACHED_PAGE, DISCARDED_PAGE, + TOTAL_PAGE, NUM_OF_GCMA_STAT, }; diff --git a/mm/gcma.c b/mm/gcma.c index 6fc98f3e9c2d..6a2eef774f80 100644 --- a/mm/gcma.c +++ b/mm/gcma.c @@ -307,6 +307,7 @@ int register_gcma_area(const char *name, phys_addr_t base, phys_addr_t size) INIT_LIST_HEAD(&area->free_pages); spin_lock_init(&area->free_pages_lock); + gcma_stat_add(TOTAL_PAGE, page_count); for (i = 0; i < page_count; i++) { page = pfn_to_page(pfn + i); set_area_id(page, area_id); @@ -621,6 +622,7 @@ void gcma_alloc_range(unsigned long start_pfn, unsigned long end_pfn) __gcma_discard_range(area, s_pfn, e_pfn); } + gcma_stat_add(ALLOCATED_PAGE, end_pfn - start_pfn + 1); } EXPORT_SYMBOL_GPL(gcma_alloc_range); @@ -659,6 +661,7 @@ void gcma_free_range(unsigned long start_pfn, unsigned long end_pfn) } local_irq_enable(); + gcma_stat_sub(ALLOCATED_PAGE, end_pfn - start_pfn + 1); } EXPORT_SYMBOL_GPL(gcma_free_range); diff --git a/mm/gcma_sysfs.c b/mm/gcma_sysfs.c index c1eaabbb6fdb..981cfa9b84aa 100644 --- a/mm/gcma_sysfs.c +++ b/mm/gcma_sysfs.c @@ -23,6 +23,11 @@ void gcma_stat_add(enum gcma_stat_type type, unsigned long delta) atomic64_add(delta, &gcma_stats[type]); } +void gcma_stat_sub(enum gcma_stat_type type, unsigned long delta) +{ + atomic64_sub(delta, &gcma_stats[type]); +} + u64 gcma_stat_get(enum gcma_stat_type type) { return (u64)atomic64_read(&gcma_stats[type]); @@ -36,6 +41,13 @@ EXPORT_SYMBOL_GPL(gcma_stat_get); #define GCMA_ATTR_RO(_name) \ static struct kobj_attribute _name##_attr = __ATTR_RO(_name) +static ssize_t allocated_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[ALLOCATED_PAGE])); +} +GCMA_ATTR_RO(allocated); + static ssize_t stored_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -71,12 +83,21 @@ static ssize_t discarded_show(struct kobject *kobj, } GCMA_ATTR_RO(discarded); +static ssize_t total_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&gcma_stats[TOTAL_PAGE])); +} +GCMA_ATTR_RO(total); + static struct attribute *gcma_attrs[] = { + &allocated_attr.attr, &stored_attr.attr, &loaded_attr.attr, &evicted_attr.attr, &cached_attr.attr, &discarded_attr.attr, + &total_attr.attr, NULL, }; ATTRIBUTE_GROUPS(gcma); diff --git a/mm/gcma_sysfs.h b/mm/gcma_sysfs.h index cf93302b7e4f..b1dedf5804d8 100644 --- a/mm/gcma_sysfs.h +++ b/mm/gcma_sysfs.h @@ -6,11 +6,14 @@ void gcma_stat_inc(enum gcma_stat_type type); void gcma_stat_dec(enum gcma_stat_type type); void gcma_stat_add(enum gcma_stat_type type, unsigned long delta); +void gcma_stat_sub(enum gcma_stat_type type, unsigned long delta); #else /* CONFIG_GCMA_SYSFS */ static inline void gcma_stat_inc(enum gcma_stat_type type) {} static inline void gcma_stat_dec(enum gcma_stat_type type) {} static inline void gcma_stat_add(enum gcma_stat_type type, unsigned long delta) {} +static inline void gcma_stat_sub(enum gcma_stat_type type, + unsigned long delta) {} #endif /* CONFIG_GCMA_SYSFS */ #endif