diff --git a/drivers/soc/qcom/mem-offline.c b/drivers/soc/qcom/mem-offline.c index fa5a912149b7..2964948a8a1a 100644 --- a/drivers/soc/qcom/mem-offline.c +++ b/drivers/soc/qcom/mem-offline.c @@ -46,6 +46,7 @@ static atomic_t target_migrate_pages = ATOMIC_INIT(0); static u32 offline_granule; static bool is_rpm_controller; static bool has_pend_offline_req; +static atomic_long_t totalram_pages_with_offline = ATOMIC_INIT(0); #define MODULE_CLASS_NAME "mem-offline" #define MIGRATE_TIMEOUT_SEC (20) @@ -101,6 +102,29 @@ static void fill_movable_zone_fn(struct work_struct *work); static DECLARE_WORK(fill_movable_zone_work, fill_movable_zone_fn); static DEFINE_MUTEX(page_migrate_lock); +unsigned long get_totalram_pages_count_inc_offlined(void) +{ + struct sysinfo i; + unsigned long totalram_with_offline; + + si_meminfo(&i); + totalram_with_offline = + (unsigned long)atomic_long_read(&totalram_pages_with_offline); + + if (i.totalram < totalram_with_offline) + i.totalram = totalram_with_offline; + + return i.totalram; +} + +static void update_totalram_snapshot(void) +{ + unsigned long totalram_with_offline; + + totalram_with_offline = get_totalram_pages_count_inc_offlined(); + atomic_long_set(&totalram_pages_with_offline, totalram_with_offline); +} + static void clear_pgtable_mapping(phys_addr_t start, phys_addr_t end) { unsigned long size = end - start; @@ -673,6 +697,7 @@ static int mem_event_callback(struct notifier_block *self, break; case MEM_ONLINE: + update_totalram_snapshot(); delay = ktime_ms_delta(ktime_get(), cur); record_stat(sec_nr, delay, MEMORY_ONLINE); cur = 0; @@ -680,6 +705,7 @@ static int mem_event_callback(struct notifier_block *self, (void *)sec_nr); break; case MEM_GOING_OFFLINE: + update_totalram_snapshot(); pr_debug("mem-offline: MEM_GOING_OFFLINE : start = 0x%llx end = 0x%llx\n", start_addr, end_addr); ++mem_info[(sec_nr - start_section_nr + MEMORY_OFFLINE * diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 0b10af0be77f..c69d9153f0e1 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -78,7 +78,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v) pages[lru] = global_node_page_state(NR_LRU_BASE + lru); available = si_mem_available(); - i.totalram += get_offlined_pages_count(); + +#ifdef CONFIG_QCOM_MEM_OFFLINE + i.totalram = get_totalram_pages_count_inc_offlined(); +#endif + sreclaimable = global_node_page_state(NR_SLAB_RECLAIMABLE); sunreclaim = global_node_page_state(NR_SLAB_UNRECLAIMABLE); diff --git a/include/linux/memory.h b/include/linux/memory.h index ebda8bf060a4..cdedbd7bfef2 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -39,6 +39,10 @@ int arch_get_memory_phys_device(unsigned long start_pfn); unsigned long memory_block_size_bytes(void); int set_memory_block_size_order(unsigned int order); +#ifdef CONFIG_QCOM_MEM_OFFLINE +unsigned long get_totalram_pages_count_inc_offlined(void); +#endif + /* These states are exposed to userspace as text strings in sysfs */ #define MEM_ONLINE (1<<0) /* exposed to userspace */ #define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */