Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / parisc / mm / init.c
index cac3758..6317125 100644 (file)
@@ -6,6 +6,7 @@
  *    changed by Philipp Rumpf
  *  Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  *  Copyright 2004 Randolph Chung (tausq@debian.org)
+ *  Copyright 2006 Helge Deller (deller@gmx.de)
  *
  */
 
@@ -36,9 +37,9 @@ extern char _end;     /* end of BSS, defined by linker */
 extern char __init_begin, __init_end;
 
 #ifdef CONFIG_DISCONTIGMEM
-struct node_map_data node_data[MAX_NUMNODES];
-bootmem_data_t bmem_data[MAX_NUMNODES];
-unsigned char pfnnid_map[PFNNID_MAP_MAX];
+struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
+bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly;
+unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
 #endif
 
 static struct resource data_resource = {
@@ -58,14 +59,14 @@ static struct resource pdcdata_resource = {
        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM,
 };
 
-static struct resource sysram_resources[MAX_PHYSMEM_RANGES];
+static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
 
 /* The following array is initialized from the firmware specific
  * information retrieved in kernel/inventory.c.
  */
 
-physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES];
-int npmem_ranges;
+physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
+int npmem_ranges __read_mostly;
 
 #ifdef __LP64__
 #define MAX_MEM         (~0UL)
@@ -73,7 +74,7 @@ int npmem_ranges;
 #define MAX_MEM         (3584U*1024U*1024U)
 #endif /* !__LP64__ */
 
-static unsigned long mem_limit = MAX_MEM;
+static unsigned long mem_limit __read_mostly = MAX_MEM;
 
 static void __init mem_limit_func(void)
 {
@@ -300,6 +301,13 @@ static void __init setup_bootmem(void)
                        max_pfn = start_pfn + npages;
        }
 
+       /* IOMMU is always used to access "high mem" on those boxes
+        * that can support enough mem that a PCI device couldn't
+        * directly DMA to any physical addresses.
+        * ISA DMA support will need to revisit this.
+        */
+       max_low_pfn = max_pfn;
+
        if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) {
                printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n");
                BUG();
@@ -364,17 +372,11 @@ static void __init setup_bootmem(void)
 
 void free_initmem(void)
 {
-       /* FIXME: */
-#if 0
-       printk(KERN_INFO "NOT FREEING INITMEM (%dk)\n",
-                       (&__init_end - &__init_begin) >> 10);
-       return;
-#else
-       unsigned long addr;
-       
+       unsigned long addr, init_begin, init_end;
+
        printk(KERN_INFO "Freeing unused kernel memory: ");
 
-#if 1
+#ifdef CONFIG_DEBUG_KERNEL
        /* Attempt to catch anyone trying to execute code here
         * by filling the page with BRK insns.
         * 
@@ -394,10 +396,13 @@ void free_initmem(void)
        local_irq_enable();
 #endif
        
-       addr = (unsigned long)(&__init_begin);
-       for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+       /* align __init_begin and __init_end to page size,
+          ignoring linker script where we might have tried to save RAM */
+       init_begin = PAGE_ALIGN((unsigned long)(&__init_begin));
+       init_end   = PAGE_ALIGN((unsigned long)(&__init_end));
+       for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
-               set_page_count(virt_to_page(addr), 1);
+               init_page_count(virt_to_page(addr));
                free_page(addr);
                num_physpages++;
                totalram_pages++;
@@ -406,9 +411,21 @@ void free_initmem(void)
        /* set up a new led state on systems shipped LED State panel */
        pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
        
-       printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10);
-#endif
+       printk("%luk freed\n", (init_end - init_begin) >> 10);
+}
+
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void)
+{
+       extern char __start_rodata, __end_rodata;
+       /* rodata memory was already mapped with KERNEL_RO access rights by
+           pagetable_init() and map_pages(). No need to do additional stuff here */
+       printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n",
+               (unsigned long)(&__end_rodata - &__start_rodata) >> 10);
 }
+#endif
+
 
 /*
  * Just an arbitrary offset to serve as a "hole" between mapping areas
@@ -431,11 +448,11 @@ void free_initmem(void)
 #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
                                     & ~(VM_MAP_OFFSET-1)))
 
-void *vmalloc_start;
+void *vmalloc_start __read_mostly;
 EXPORT_SYMBOL(vmalloc_start);
 
 #ifdef CONFIG_PA11
-unsigned long pcxl_dma_start;
+unsigned long pcxl_dma_start __read_mostly;
 #endif
 
 void __init mem_init(void)
@@ -470,12 +487,7 @@ void __init mem_init(void)
 
 }
 
-int do_check_pgt_cache(int low, int high)
-{
-       return 0;
-}
-
-unsigned long *empty_zero_page;
+unsigned long *empty_zero_page __read_mostly;
 
 void show_mem(void)
 {
@@ -505,8 +517,10 @@ void show_mem(void)
 
                for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
                        struct page *p;
+                       unsigned long flags;
 
-                       p = node_mem_map(i) + j - node_start_pfn(i);
+                       pgdat_resize_lock(NODE_DATA(i), &flags);
+                       p = nid_page_nr(i, j) - node_start_pfn(i);
 
                        total++;
                        if (PageReserved(p))
@@ -517,6 +531,7 @@ void show_mem(void)
                                free++;
                        else
                                shared += page_count(p) - 1;
+                       pgdat_resize_unlock(NODE_DATA(i), &flags);
                }
        }
 #endif
@@ -628,11 +643,13 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_padd
                                 * Map the fault vector writable so we can
                                 * write the HPMC checksum.
                                 */
+#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
                                if (address >= ro_start && address < ro_end
                                                        && address != fv_addr
                                                        && address != gw_addr)
                                    pte = __mk_pte(address, PAGE_KERNEL_RO);
                                else
+#endif
                                    pte = __mk_pte(address, pgprot);
 
                                if (address >= end_paddr)
@@ -680,7 +697,7 @@ static void __init pagetable_init(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_end && initrd_end > mem_limit) {
-               printk("initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
+               printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
                map_pages(initrd_start, __pa(initrd_start),
                        initrd_end - initrd_start, PAGE_KERNEL);
        }
@@ -782,8 +799,6 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
 EXPORT_SYMBOL(map_hpux_gateway_page);
 #endif
 
-extern void flush_tlb_all_local(void);
-
 void __init paging_init(void)
 {
        int i;
@@ -792,7 +807,7 @@ void __init paging_init(void)
        pagetable_init();
        gateway_init();
        flush_cache_all_local(); /* start with known state */
-       flush_tlb_all_local();
+       flush_tlb_all_local(NULL);
 
        for (i = 0; i < npmem_ranges; i++) {
                unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 };
@@ -865,8 +880,7 @@ unsigned long alloc_sid(void)
                        flush_tlb_all(); /* flush_tlb_all() calls recycle_sids() */
                        spin_lock(&sid_lock);
                }
-               if (free_space_ids == 0)
-                       BUG();
+               BUG_ON(free_space_ids == 0);
        }
 
        free_space_ids--;
@@ -890,8 +904,7 @@ void free_sid(unsigned long spaceid)
 
        spin_lock(&sid_lock);
 
-       if (*dirty_space_offset & (1L << index))
-           BUG(); /* attempt to free space id twice */
+       BUG_ON(*dirty_space_offset & (1L << index)); /* attempt to free space id twice */
 
        *dirty_space_offset |= (1L << index);
        dirty_space_ids++;
@@ -966,7 +979,7 @@ static void recycle_sids(void)
 
 static unsigned long recycle_ndirty;
 static unsigned long recycle_dirty_array[SID_ARRAY_SIZE];
-static unsigned int recycle_inuse = 0;
+static unsigned int recycle_inuse;
 
 void flush_tlb_all(void)
 {
@@ -975,15 +988,13 @@ void flush_tlb_all(void)
        do_recycle = 0;
        spin_lock(&sid_lock);
        if (dirty_space_ids > RECYCLE_THRESHOLD) {
-           if (recycle_inuse) {
-               BUG();  /* FIXME: Use a semaphore/wait queue here */
-           }
+           BUG_ON(recycle_inuse);  /* FIXME: Use a semaphore/wait queue here */
            get_dirty_sids(&recycle_ndirty,recycle_dirty_array);
            recycle_inuse++;
            do_recycle++;
        }
        spin_unlock(&sid_lock);
-       on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
+       on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
        if (do_recycle) {
            spin_lock(&sid_lock);
            recycle_sids(recycle_ndirty,recycle_dirty_array);
@@ -995,7 +1006,7 @@ void flush_tlb_all(void)
 void flush_tlb_all(void)
 {
        spin_lock(&sid_lock);
-       flush_tlb_all_local();
+       flush_tlb_all_local(NULL);
        recycle_sids();
        spin_unlock(&sid_lock);
 }
@@ -1004,16 +1015,15 @@ void flush_tlb_all(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-#if 0
-       if (start < end)
-               printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+       if (start >= end)
+               return;
+       printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
        for (; start < end; start += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(start));
-               set_page_count(virt_to_page(start), 1);
+               init_page_count(virt_to_page(start));
                free_page(start);
                num_physpages++;
                totalram_pages++;
        }
-#endif
 }
 #endif