proc/meminfo: include offlined region for mem total

When memory block is logically offlined, it is still part of System RAM
but is inactive, and can be made active or Onlined anytime. Though from
the perspective of kernel which is giving the “current usable memory in
the system" info to userspace via MemTotal, when active-mode memory
onlining is enabled, the offlined blocks can be onlined when there is
memory pressure (on demand) and thus can be added as part of total
available memory in the system.

Change-Id: I3d6acbe5b05c33c60ac3f1346977f5a72e4d5897
Signed-off-by: Sudarshan Rajagopalan <sudaraja@codeaurora.org>
This commit is contained in:
Sudarshan Rajagopalan 2020-08-25 17:24:14 -07:00 committed by Gerrit - the friendly Code Review server
parent b5b61d0f51
commit dc00b6d99a
3 changed files with 33 additions and 0 deletions

View file

@ -982,3 +982,32 @@ int for_each_memory_block(void *arg, walk_memory_blocks_func_t func)
return bus_for_each_dev(&memory_subsys, NULL, &cb_data, return bus_for_each_dev(&memory_subsys, NULL, &cb_data,
for_each_memory_block_cb); for_each_memory_block_cb);
} }
static int check_memblock_offlined(struct memory_block *mem, void *arg)
{
unsigned long *nr_pages_offlined = (unsigned long *)arg;
if (is_memblock_offlined(mem))
*nr_pages_offlined += memory_block_size_bytes() / PAGE_SIZE;
return 0;
}
/**
* get_offlined_pages_count - get total pages offlined in the system
*
* This function walks through all the memory blocks present and gives
* the total offlined pages count in the system.
*
*/
unsigned long get_offlined_pages_count(void)
{
unsigned long nr_pages_offlined = 0;
lock_device_hotplug_sysfs();
for_each_memory_block(&nr_pages_offlined, check_memblock_offlined);
unlock_device_hotplug();
return nr_pages_offlined;
}

View file

@ -6,6 +6,7 @@
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/mmzone.h> #include <linux/mmzone.h>
#include <linux/memory.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
@ -53,6 +54,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
pages[lru] = global_node_page_state(NR_LRU_BASE + lru); pages[lru] = global_node_page_state(NR_LRU_BASE + lru);
available = si_mem_available(); available = si_mem_available();
i.totalram += get_offlined_pages_count();
sreclaimable = global_node_page_state(NR_SLAB_RECLAIMABLE); sreclaimable = global_node_page_state(NR_SLAB_RECLAIMABLE);
sunreclaim = global_node_page_state(NR_SLAB_UNRECLAIMABLE); sunreclaim = global_node_page_state(NR_SLAB_UNRECLAIMABLE);

View file

@ -131,11 +131,13 @@ extern int for_each_memory_block(void *arg, walk_memory_blocks_func_t func);
}) })
#define register_hotmemory_notifier(nb) register_memory_notifier(nb) #define register_hotmemory_notifier(nb) register_memory_notifier(nb)
#define unregister_hotmemory_notifier(nb) unregister_memory_notifier(nb) #define unregister_hotmemory_notifier(nb) unregister_memory_notifier(nb)
extern unsigned long get_offlined_pages_count(void);
#else #else
#define hotplug_memory_notifier(fn, pri) ({ 0; }) #define hotplug_memory_notifier(fn, pri) ({ 0; })
/* These aren't inline functions due to a GCC bug. */ /* These aren't inline functions due to a GCC bug. */
#define register_hotmemory_notifier(nb) ({ (void)(nb); 0; }) #define register_hotmemory_notifier(nb) ({ (void)(nb); 0; })
#define unregister_hotmemory_notifier(nb) ({ (void)(nb); }) #define unregister_hotmemory_notifier(nb) ({ (void)(nb); })
static inline unsigned long get_offlined_pages_count(void) { return 0; }
#endif #endif
/* /*