diff -urNp ref/fs/proc/proc_misc.c 2.4.20pre5aa1/fs/proc/proc_misc.c --- ref/fs/proc/proc_misc.c Fri Aug 30 03:22:09 2002 +++ 2.4.20pre5aa1/fs/proc/proc_misc.c Fri Aug 30 03:22:13 2002 @@ -153,7 +153,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 ; /* @@ -207,6 +207,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 ref/include/linux/highmem.h 2.4.20pre5aa1/include/linux/highmem.h --- ref/include/linux/highmem.h Fri Aug 30 03:22:03 2002 +++ 2.4.20pre5aa1/include/linux/highmem.h Fri Aug 30 03:22:13 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 ref/include/linux/mm.h 2.4.20pre5aa1/include/linux/mm.h --- ref/include/linux/mm.h Fri Aug 30 03:22:10 2002 +++ 2.4.20pre5aa1/include/linux/mm.h Fri Aug 30 03:22:13 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 ref/include/linux/swap.h 2.4.20pre5aa1/include/linux/swap.h --- ref/include/linux/swap.h Fri Aug 30 03:21:59 2002 +++ 2.4.20pre5aa1/include/linux/swap.h Fri Aug 30 03:22:13 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 ref/mm/numa.c 2.4.20pre5aa1/mm/numa.c --- ref/mm/numa.c Fri Aug 30 03:22:10 2002 +++ 2.4.20pre5aa1/mm/numa.c Fri Aug 30 03:22:13 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 ref/mm/page_alloc.c 2.4.20pre5aa1/mm/page_alloc.c --- ref/mm/page_alloc.c Fri Aug 30 03:22:10 2002 +++ 2.4.20pre5aa1/mm/page_alloc.c Fri Aug 30 03:29:59 2002 @@ -508,6 +508,20 @@ unsigned int nr_free_pages (void) } /* + * Total amount of free (allocatable) RAM for a given pg_data_t: + */ +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) @@ -539,17 +553,22 @@ unsigned int nr_free_buffer_pages (void) } #if CONFIG_HIGHMEM +inline unsigned int nr_free_highpages_pgdat (pg_data_t *pgdat) +{ + return pgdat->node_zones[ZONE_HIGHMEM].free_pages; +} + unsigned int nr_free_highpages (void) { pg_data_t *pgdat; unsigned int pages = 0; for_each_pgdat(pgdat) - pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages; + pages += nr_free_highpages_pgdat(pgdat); return pages; } -#endif +#endif /* CONFIG_HIGHMEM */ /* * If it returns non zero it means there's lots of ram "free"