lkml.org 
[lkml]   [2002]   [Oct]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] per-node (NUMA) meminfo for sysfs Topology 2.5.45 (3/5)
Matthew Dobson wrote:
>
> Linus,
> This series of patches creates a directory-based Topology in sysfs
> (driverfs). This includes the per-node meminfo patch you wanted, as
> well as UP/SMP/NUMA topology.
> There were discussions between myself, Andrew, Rusty, and Patrick,
> and these are what we agreed on.
>
> (1/5) Core sysfs Topology:
> This patch creates the generic structures that are (will be)
> embedded in the per-arch structures. Also creates calls to
> register these generic structures (CPUs, MemBlks, & Nodes).
>
> Note that without arch-specific structures in which to embed
> these structures, and an arch-specific initialization routine,
> these functions/structures remain unused.
>
> (2/5) i386 sysfs Topology
> This patch creates the i386 specific files/functions/structures
> to implement driverfs Topology. These structures have the
> generic CPU/MemBlk/Node structures embedded in them.
>
> This patch also creates the arch-specific initialization routine
> to instantiate the topology.
>
> (3/5) per-node (NUMA) meminfo for sysfs Topology
> This patch adds code to DriverFS Topology to expose per-node
> memory statistics.
> This information is exposed via the nodeX/meminfo file.
>
> The patch also adds 2 helper functions to gather per-node memory
> info.
>
> (4/5) memblk_online_map
> This patch creates a memblk_online_map, much like
> cpu_online_map. It also creates the standard helper functions,
> ie: memblk_online(), num_online_memblks(), memblk_set_online(),
> memblk_set_offline().
>
> This is used by driverFS topology to keep track of which memory
> blocks are in the system and online.
>
> (5/5) node_online_map
> This patch creates a node_online_map, much like cpu_online_map.
> It also creates the standard helper functions, ie:
> node_online(), num_online_nodes(), node_set_online(),
> node_set_offline().
>
> This is used by driverFS topology to keep track of which Nodes
> are in the system and online.
>
> Cheers!
>
> -Matt
diff -Nur --exclude-from=/usr/src/.dontdiff linux-2.5.45-base/drivers/base/node.c linux-2.5.45-meminfo_additions/drivers/base/node.c
--- linux-2.5.45-base/drivers/base/node.c Wed Oct 30 18:00:55 2002
+++ linux-2.5.45-meminfo_additions/drivers/base/node.c Wed Oct 30 18:00:24 2002
@@ -35,6 +35,34 @@
}
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.
@@ -57,6 +85,7 @@
error = sys_register_root(&node->sysroot);
if (!error){
device_create_file(&node->sysroot.dev, &dev_attr_cpumap);
+ device_create_file(&node->sysroot.dev, &dev_attr_meminfo);
}
return error;
}
diff -Nur --exclude-from=/usr/src/.dontdiff linux-2.5.45-base/include/linux/mm.h linux-2.5.45-meminfo_additions/include/linux/mm.h
--- linux-2.5.45-base/include/linux/mm.h Wed Oct 30 16:41:39 2002
+++ linux-2.5.45-meminfo_additions/include/linux/mm.h Wed Oct 30 17:56:28 2002
@@ -449,6 +449,9 @@
extern void mem_init(void);
extern void show_mem(void);
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 int can_share_swap_page(struct page *);
diff -Nur --exclude-from=/usr/src/.dontdiff linux-2.5.45-base/include/linux/swap.h linux-2.5.45-meminfo_additions/include/linux/swap.h
--- linux-2.5.45-base/include/linux/swap.h Wed Oct 30 16:41:37 2002
+++ linux-2.5.45-meminfo_additions/include/linux/swap.h Wed Oct 30 17:56:28 2002
@@ -131,6 +131,9 @@
extern unsigned long totalram_pages;
extern unsigned long totalhigh_pages;
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_pagecache_pages(void);

diff -Nur --exclude-from=/usr/src/.dontdiff linux-2.5.45-base/mm/page_alloc.c linux-2.5.45-meminfo_additions/mm/page_alloc.c
--- linux-2.5.45-base/mm/page_alloc.c Wed Oct 30 16:41:51 2002
+++ linux-2.5.45-meminfo_additions/mm/page_alloc.c Wed Oct 30 17:56:28 2002
@@ -594,6 +594,18 @@
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)
{
pg_data_t *pgdat;
@@ -721,6 +733,19 @@
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))

/*
\
 
 \ /
  Last update: 2005-03-22 13:30    [W:1.040 / U:0.128 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site