Commit ef890de6 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] NUMA meminfo for driverfs Topology

From Matthew Dobson.

Create nodeX/meminfo files for DriverFS Topology.

This patch adds code to DriverFS Topology to expose per-node memory
statistics.  This information is exposed via: cat nodeX/meminfo

The patch also adds 2 helper functions to gather per-node memory info.
parent de642de7
...@@ -35,6 +35,34 @@ static ssize_t node_read_cpumap(struct device * dev, char * buf, size_t count, l ...@@ -35,6 +35,34 @@ static ssize_t node_read_cpumap(struct device * dev, char * buf, size_t count, l
} }
static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL); static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
#define K(x) ((x) << (PAGE_SHIFT - 10))
static ssize_t node_read_meminfo(struct device * dev, char * buf, size_t count, loff_t off)
{
struct sys_root *node = to_root(dev);
int nid = node->id;
struct sysinfo i;
si_meminfo_node(&i, nid);
return off ? 0 : sprintf(buf, "\n"
"Node %d MemTotal: %8lu kB\n"
"Node %d MemFree: %8lu kB\n"
"Node %d MemUsed: %8lu kB\n"
"Node %d HighTotal: %8lu kB\n"
"Node %d HighFree: %8lu kB\n"
"Node %d LowTotal: %8lu kB\n"
"Node %d LowFree: %8lu kB\n",
nid, K(i.totalram),
nid, K(i.freeram),
nid, K(i.totalram-i.freeram),
nid, K(i.totalhigh),
nid, K(i.freehigh),
nid, K(i.totalram-i.totalhigh),
nid, K(i.freeram-i.freehigh));
return 0;
}
#undef K
static DEVICE_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
/* /*
* register_node - Setup a driverfs device for a node. * register_node - Setup a driverfs device for a node.
...@@ -54,6 +82,7 @@ void __init register_node(struct node *node, int num, struct node *parent) ...@@ -54,6 +82,7 @@ void __init register_node(struct node *node, int num, struct node *parent)
node->sysroot.dev.bus = &system_bus_type; node->sysroot.dev.bus = &system_bus_type;
if (!sys_register_root(&node->sysroot)){ if (!sys_register_root(&node->sysroot)){
device_create_file(&node->sysroot.dev, &dev_attr_cpumap); device_create_file(&node->sysroot.dev, &dev_attr_cpumap);
device_create_file(&node->sysroot.dev, &dev_attr_meminfo);
} }
} }
......
...@@ -439,6 +439,9 @@ extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap, ...@@ -439,6 +439,9 @@ extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
extern void mem_init(void); extern void mem_init(void);
extern void show_mem(void); extern void show_mem(void);
extern void si_meminfo(struct sysinfo * val); extern void si_meminfo(struct sysinfo * val);
#ifdef CONFIG_NUMA
extern void si_meminfo_node(struct sysinfo *val, int nid);
#endif
extern void swapin_readahead(swp_entry_t); extern void swapin_readahead(swp_entry_t);
extern int can_share_swap_page(struct page *); extern int can_share_swap_page(struct page *);
......
...@@ -131,6 +131,9 @@ extern int nr_swap_pages; ...@@ -131,6 +131,9 @@ extern int nr_swap_pages;
extern unsigned long totalram_pages; extern unsigned long totalram_pages;
extern unsigned long totalhigh_pages; extern unsigned long totalhigh_pages;
extern unsigned int nr_free_pages(void); extern unsigned int nr_free_pages(void);
#ifdef CONFIG_NUMA
extern unsigned int nr_free_pages_pgdat(pg_data_t *pgdat);
#endif
extern unsigned int nr_free_buffer_pages(void); extern unsigned int nr_free_buffer_pages(void);
extern unsigned int nr_free_pagecache_pages(void); extern unsigned int nr_free_pagecache_pages(void);
......
...@@ -595,6 +595,18 @@ unsigned int nr_used_zone_pages(void) ...@@ -595,6 +595,18 @@ unsigned int nr_used_zone_pages(void)
return pages; return pages;
} }
#ifdef CONFIG_NUMA
unsigned int nr_free_pages_pgdat(pg_data_t *pgdat)
{
unsigned int i, sum = 0;
for (i = 0; i < MAX_NR_ZONES; i++)
sum += pgdat->node_zones[i].free_pages;
return sum;
}
#endif
static unsigned int nr_free_zone_pages(int offset) static unsigned int nr_free_zone_pages(int offset)
{ {
pg_data_t *pgdat; pg_data_t *pgdat;
...@@ -722,6 +734,19 @@ void si_meminfo(struct sysinfo *val) ...@@ -722,6 +734,19 @@ void si_meminfo(struct sysinfo *val)
val->mem_unit = PAGE_SIZE; val->mem_unit = PAGE_SIZE;
} }
#ifdef CONFIG_NUMA
void si_meminfo_node(struct sysinfo *val, int nid)
{
pg_data_t *pgdat = NODE_DATA(nid);
val->totalram = pgdat->node_size;
val->freeram = nr_free_pages_pgdat(pgdat);
val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].spanned_pages;
val->freehigh = pgdat->node_zones[ZONE_HIGHMEM].free_pages;
val->mem_unit = PAGE_SIZE;
}
#endif
#define K(x) ((x) << (PAGE_SHIFT-10)) #define K(x) ((x) << (PAGE_SHIFT-10))
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment