[PATCH] optional ZONE_DMA: optional ZONE_DMA for ia64
[sfrench/cifs-2.6.git] / arch / ia64 / mm / contig.c
index e004143ba86b7f22ce19d8a002a3cbd944b94c7a..ca4d41e5f177563c5739816c14ee563dc51ed87b 100644 (file)
 #include <asm/mca.h>
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
-static unsigned long num_dma_physpages;
 static unsigned long max_gap;
 #endif
 
 /**
- * show_mem - display a memory statistics summary
+ * show_mem - give short summary of memory stats
  *
- * Just walks the pages in the system and describes where they're allocated.
+ * Shows a simple page count of reserved and used pages in the system.
+ * For discontig machines, it does this on a per-pgdat basis.
  */
-void
-show_mem (void)
+void show_mem(void)
 {
-       int i, total = 0, reserved = 0;
-       int shared = 0, cached = 0;
+       int i, total_reserved = 0;
+       int total_shared = 0, total_cached = 0;
+       unsigned long total_present = 0;
+       pg_data_t *pgdat;
 
-       printk("Mem-info:\n");
+       printk(KERN_INFO "Mem-info:\n");
        show_free_areas();
-
-       printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-       i = max_mapnr;
-       for (i = 0; i < max_mapnr; i++) {
-               if (!pfn_valid(i)) {
+       printk(KERN_INFO "Free swap:       %6ldkB\n",
+              nr_swap_pages<<(PAGE_SHIFT-10));
+       printk(KERN_INFO "Node memory in pages:\n");
+       for_each_online_pgdat(pgdat) {
+               unsigned long present;
+               unsigned long flags;
+               int shared = 0, cached = 0, reserved = 0;
+
+               pgdat_resize_lock(pgdat, &flags);
+               present = pgdat->node_present_pages;
+               for(i = 0; i < pgdat->node_spanned_pages; i++) {
+                       struct page *page;
+                       if (pfn_valid(pgdat->node_start_pfn + i))
+                               page = pfn_to_page(pgdat->node_start_pfn + i);
+                       else {
 #ifdef CONFIG_VIRTUAL_MEM_MAP
-                       if (max_gap < LARGE_GAP)
-                               continue;
-                       i = vmemmap_find_next_valid_pfn(0, i) - 1;
+                               if (max_gap < LARGE_GAP)
+                                       continue;
 #endif
-                       continue;
+                               i = vmemmap_find_next_valid_pfn(pgdat->node_id,
+                                        i) - 1;
+                               continue;
+                       }
+                       if (PageReserved(page))
+                               reserved++;
+                       else if (PageSwapCache(page))
+                               cached++;
+                       else if (page_count(page))
+                               shared += page_count(page)-1;
                }
-               total++;
-               if (PageReserved(mem_map+i))
-                       reserved++;
-               else if (PageSwapCache(mem_map+i))
-                       cached++;
-               else if (page_count(mem_map + i))
-                       shared += page_count(mem_map + i) - 1;
+               pgdat_resize_unlock(pgdat, &flags);
+               total_present += present;
+               total_reserved += reserved;
+               total_cached += cached;
+               total_shared += shared;
+               printk(KERN_INFO "Node %4d:  RAM: %11ld, rsvd: %8d, "
+                      "shrd: %10d, swpd: %10d\n", pgdat->node_id,
+                      present, reserved, shared, cached);
        }
-       printk("%d pages of RAM\n", total);
-       printk("%d reserved pages\n", reserved);
-       printk("%d pages shared\n", shared);
-       printk("%d pages swap cached\n", cached);
-       printk("%ld pages in page table cache\n",
-               pgtable_quicklist_total_size());
+       printk(KERN_INFO "%ld pages of RAM\n", total_present);
+       printk(KERN_INFO "%d reserved pages\n", total_reserved);
+       printk(KERN_INFO "%d pages shared\n", total_shared);
+       printk(KERN_INFO "%d pages swap cached\n", total_cached);
+       printk(KERN_INFO "Total of %ld pages in page table cache\n",
+              pgtable_quicklist_total_size());
+       printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
 }
 
+
 /* physical address where the bootmem map is located */
 unsigned long bootmap_start;
 
@@ -174,6 +196,12 @@ find_memory (void)
        reserve_bootmem(bootmap_start, bootmap_size);
 
        find_initrd();
+
+#ifdef CONFIG_CRASH_DUMP
+       /* If we are doing a crash dump, we still need to know the real mem
+        * size before original memory map is reset. */
+       saved_max_pfn = max_pfn;
+#endif
 }
 
 #ifdef CONFIG_SMP
@@ -218,18 +246,6 @@ count_pages (u64 start, u64 end, void *arg)
        return 0;
 }
 
-#ifdef CONFIG_VIRTUAL_MEM_MAP
-static int
-count_dma_pages (u64 start, u64 end, void *arg)
-{
-       unsigned long *count = arg;
-
-       if (start < MAX_DMA_ADDRESS)
-               *count += (min(end, MAX_DMA_ADDRESS) - start) >> PAGE_SHIFT;
-       return 0;
-}
-#endif
-
 /*
  * Set up the page tables.
  */
@@ -238,45 +254,24 @@ void __init
 paging_init (void)
 {
        unsigned long max_dma;
-       unsigned long zones_size[MAX_NR_ZONES];
-#ifdef CONFIG_VIRTUAL_MEM_MAP
-       unsigned long zholes_size[MAX_NR_ZONES];
-#endif
-
-       /* initialize mem_map[] */
-
-       memset(zones_size, 0, sizeof(zones_size));
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
 
        num_physpages = 0;
        efi_memmap_walk(count_pages, &num_physpages);
 
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+#ifdef CONFIG_ZONE_DMA
        max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_DMA] = max_dma;
+#endif
+       max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
-       memset(zholes_size, 0, sizeof(zholes_size));
-
-       num_dma_physpages = 0;
-       efi_memmap_walk(count_dma_pages, &num_dma_physpages);
-
-       if (max_low_pfn < max_dma) {
-               zones_size[ZONE_DMA] = max_low_pfn;
-               zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages;
-       } else {
-               zones_size[ZONE_DMA] = max_dma;
-               zholes_size[ZONE_DMA] = max_dma - num_dma_physpages;
-               if (num_physpages > num_dma_physpages) {
-                       zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
-                       zholes_size[ZONE_NORMAL] =
-                               ((max_low_pfn - max_dma) -
-                                (num_physpages - num_dma_physpages));
-               }
-       }
-
+       efi_memmap_walk(register_active_ranges, NULL);
        efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
        if (max_gap < LARGE_GAP) {
                vmem_map = (struct page *) 0;
-               free_area_init_node(0, NODE_DATA(0), zones_size, 0,
-                                   zholes_size);
+               free_area_init_nodes(max_zone_pfns);
        } else {
                unsigned long map_size;
 
@@ -288,20 +283,19 @@ paging_init (void)
                vmem_map = (struct page *) vmalloc_end;
                efi_memmap_walk(create_mem_map_page_table, NULL);
 
-               NODE_DATA(0)->node_mem_map = vmem_map;
-               free_area_init_node(0, NODE_DATA(0), zones_size,
-                                   0, zholes_size);
+               /*
+                * alloc_node_mem_map makes an adjustment for mem_map
+                * which isn't compatible with vmem_map.
+                */
+               NODE_DATA(0)->node_mem_map = vmem_map +
+                       find_min_pfn_with_active_regions();
+               free_area_init_nodes(max_zone_pfns);
 
                printk("Virtual mem_map starts at 0x%p\n", mem_map);
        }
 #else /* !CONFIG_VIRTUAL_MEM_MAP */
-       if (max_low_pfn < max_dma)
-               zones_size[ZONE_DMA] = max_low_pfn;
-       else {
-               zones_size[ZONE_DMA] = max_dma;
-               zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
-       }
-       free_area_init(zones_size);
+       add_active_range(0, 0, max_low_pfn);
+       free_area_init_nodes(max_zone_pfns);
 #endif /* !CONFIG_VIRTUAL_MEM_MAP */
        zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }