diff -urNp pgdat-ref/fs/proc/proc_misc.c pgdat/fs/proc/proc_misc.c --- pgdat-ref/fs/proc/proc_misc.c Tue Jul 23 16:41:29 2002 +++ pgdat/fs/proc/proc_misc.c Tue Jul 23 16:41:43 2002 @@ -154,7 +154,7 @@ static int meminfo_read_proc(char *page, int count, int *eof, void *data) { struct sysinfo i; - int len; + int len, nid; int pg_size ; /* @@ -208,6 +208,27 @@ static int meminfo_read_proc(char *page, K(i.totalswap), K(i.freeswap)); +#ifdef CONFIG_DISCONTIGMEM + for (nid = 0; nid < numnodes; ++nid) { + si_meminfo_node(&i, nid); + len += sprintf(page+len, "\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)); + } +#endif + return proc_calc_metrics(page, start, off, count, eof, len); #undef B #undef K diff -urNp pgdat-ref/include/linux/highmem.h pgdat/include/linux/highmem.h --- pgdat-ref/include/linux/highmem.h Tue Jul 23 16:40:11 2002 +++ pgdat/include/linux/highmem.h Tue Jul 23 16:41:43 2002 @@ -12,6 +12,7 @@ extern struct page *highmem_start_page; /* declarations for linux/mm/highmem.c */ unsigned int nr_free_highpages(void); +inline unsigned int nr_free_highpages_pgdat(pg_data_t *pgdat); extern void init_kmap(void); extern struct buffer_head *create_bounce(int rw, struct buffer_head * bh_orig); diff -urNp pgdat-ref/include/linux/mm.h pgdat/include/linux/mm.h --- pgdat-ref/include/linux/mm.h Tue Jul 23 16:41:29 2002 +++ pgdat/include/linux/mm.h Tue Jul 23 16:41:43 2002 @@ -526,6 +526,9 @@ extern void free_area_init_node(int nid, extern void mem_init(void); extern void show_mem(void); extern void si_meminfo(struct sysinfo * val); +#ifdef CONFIG_DISCONTIGMEM +extern void si_meminfo_node(struct sysinfo *val, int nid); +#endif extern void swapin_readahead(swp_entry_t); extern struct address_space swapper_space; diff -urNp pgdat-ref/include/linux/swap.h pgdat/include/linux/swap.h --- pgdat-ref/include/linux/swap.h Tue Jul 23 16:40:10 2002 +++ pgdat/include/linux/swap.h Tue Jul 23 16:41:43 2002 @@ -84,6 +84,7 @@ extern int nr_swap_pages; #define vm_swap_full() (nr_swap_pages*2 < total_swap_pages) extern unsigned int nr_free_pages(void); +extern inline unsigned int nr_free_pages_pgdat (pg_data_t *pgdat); extern unsigned int nr_free_buffer_pages(void); extern int nr_active_pages; extern int nr_inactive_pages; diff -urNp pgdat-ref/mm/numa.c pgdat/mm/numa.c --- pgdat-ref/mm/numa.c Tue Jul 23 16:41:29 2002 +++ pgdat/mm/numa.c Tue Jul 23 17:00:52 2002 @@ -82,4 +82,26 @@ void __init free_area_init_node(int nid, memset(pgdat->valid_addr_bitmap, 0, size); } +void si_meminfo_node(struct sysinfo *val, int nid) +{ + pg_data_t *pgdat; + + val->totalram = 0; + val->freeram = 0; + val->totalhigh = 0; + val->freehigh = 0; + + pgdat = NODE_DATA(nid); + if (!pgdat) + BUG(); + val->totalram += pgdat->node_size; + val->freeram += nr_free_pages_pgdat(pgdat); +#ifdef CONFIG_HIGHMEM + val->totalhigh += pgdat->node_zones[ZONE_HIGHMEM].size; + val->freehigh += nr_free_highpages_pgdat(pgdat); +#endif + val->mem_unit = PAGE_SIZE; + return; +} + #endif /* CONFIG_DISCONTIGMEM */ diff -urNp pgdat-ref/mm/page_alloc.c pgdat/mm/page_alloc.c --- pgdat-ref/mm/page_alloc.c Tue Jul 23 16:41:29 2002 +++ pgdat/mm/page_alloc.c Tue Jul 23 16:41:43 2002 @@ -492,19 +492,31 @@ void free_exact(void * addr, unsigned in unsigned int nr_free_pages (void) { unsigned int sum; - zone_t *zone; pg_data_t *pgdat = pgdat_list; sum = 0; while (pgdat) { - for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) - sum += zone->free_pages; + sum += nr_free_pages_pgdat(pgdat); pgdat = pgdat->node_next; } return sum; } /* + * Total amount of free (allocatable) RAM for a given pg_data_t: + */ +inline unsigned int nr_free_pages_pgdat (pg_data_t *pgdat) +{ + unsigned int sum; + zone_t *zone; + + sum = 0; + for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++) + sum += zone->free_pages; + return sum; +} + +/* * Amount of free RAM allocatable as buffer memory: */ unsigned int nr_free_buffer_pages (void) @@ -544,12 +556,17 @@ unsigned int nr_free_highpages (void) unsigned int pages = 0; while (pgdat) { - pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages; + pages += nr_free_highpages_pgdat(pgdat); pgdat = pgdat->node_next; } return pages; } -#endif + +inline unsigned int nr_free_highpages_pgdat (pg_data_t *pgdat) +{ + return pgdat->node_zones[ZONE_HIGHMEM].free_pages; +} +#endif /* CONFIG_HIGHMEM */ /* * If it returns non zero it means there's lots of ram "free"