[PATCH] remove set_page_count() outside mm/
Nick Piggin [Wed, 22 Mar 2006 08:08:40 +0000 (00:08 -0800)]
set_page_count usage outside mm/ is limited to setting the refcount to 1.
Remove set_page_count from outside mm/, and replace those users with
init_page_count() and set_page_refcounted().

This allows more debug checking, and tighter control on how code is allowed
to play around with page->_count.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

40 files changed:
arch/alpha/mm/init.c
arch/arm/mm/init.c
arch/arm26/mm/init.c
arch/cris/mm/init.c
arch/frv/mm/init.c
arch/h8300/mm/init.c
arch/i386/mm/init.c
arch/ia64/mm/init.c
arch/m32r/mm/init.c
arch/m68k/mm/init.c
arch/m68k/mm/memory.c
arch/m68k/mm/motorola.c
arch/m68knommu/mm/init.c
arch/mips/arc/memory.c
arch/mips/dec/prom/memory.c
arch/mips/mips-boards/generic/memory.c
arch/mips/mips-boards/sim/sim_mem.c
arch/mips/mm/init.c
arch/mips/sgi-ip27/ip27-memory.c
arch/parisc/mm/init.c
arch/powerpc/mm/init_32.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/cell/setup.c
arch/ppc/mm/init.c
arch/s390/mm/init.c
arch/sh/mm/init.c
arch/sh64/mm/init.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/mm/init.c
arch/sparc64/mm/init.c
arch/um/kernel/mem.c
arch/x86_64/mm/init.c
arch/xtensa/mm/init.c
drivers/video/acornfb.c
include/linux/mm.h
mm/hugetlb.c
mm/internal.h
mm/page_alloc.c

index 486d794..544ac5d 100644 (file)
@@ -357,7 +357,7 @@ free_reserved_mem(void *start, void *end)
        void *__start = start;
        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((long)__start);
                totalram_pages++;
        }
index 8b276ee..b0321e9 100644 (file)
@@ -531,7 +531,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
        for (; addr < end; addr += PAGE_SIZE) {
                struct page *page = virt_to_page(addr);
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                free_page(addr);
                totalram_pages++;
        }
index 1f09a9d..e3ecaa4 100644 (file)
@@ -324,7 +324,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
        for (; addr < end; addr += PAGE_SIZE) {
                struct page *page = virt_to_page(addr);
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                free_page(addr);
                totalram_pages++;
        }
index 31a0018..b7842ff 100644 (file)
@@ -216,7 +216,7 @@ free_initmem(void)
         addr = (unsigned long)(&__init_begin);
         for (; addr < (unsigned long)(&__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);
                 totalram_pages++;
         }
index 765088e..8899aa1 100644 (file)
@@ -169,7 +169,7 @@ void __init mem_init(void)
                struct page *page = &mem_map[pfn];
 
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                __free_page(page);
                totalram_pages++;
        }
@@ -210,7 +210,7 @@ void __init free_initmem(void)
        /* next to check that the page we free is not a partial page */
        for (addr = start; addr < 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);
                totalram_pages++;
        }
@@ -230,7 +230,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
        int pages = 0;
        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);
                totalram_pages++;
                pages++;
index 1e0929d..09efc4b 100644 (file)
@@ -196,7 +196,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        int pages = 0;
        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);
                totalram_pages++;
                pages++;
@@ -219,7 +219,7 @@ free_initmem()
        /* next to check that the page we free is not a partial page */
        for (; addr + PAGE_SIZE < (unsigned long)(&__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);
                totalram_pages++;
        }
index 2700f01..7ba55a6 100644 (file)
@@ -270,7 +270,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
 
 static void __meminit free_new_highpage(struct page *page)
 {
-       set_page_count(page, 1);
+       init_page_count(page);
        __free_page(page);
        totalhigh_pages++;
 }
@@ -727,7 +727,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__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));
                memset((void *)addr, 0xcc, PAGE_SIZE);
                free_page(addr);
                totalram_pages++;
@@ -766,7 +766,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                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);
                totalram_pages++;
        }
index b38b6d2..08d94e6 100644 (file)
@@ -197,7 +197,7 @@ free_initmem (void)
        eaddr = (unsigned long) ia64_imva(__init_end);
        while (addr < eaddr) {
                ClearPageReserved(virt_to_page(addr));
-               set_page_count(virt_to_page(addr), 1);
+               init_page_count(virt_to_page(addr));
                free_page(addr);
                ++totalram_pages;
                addr += PAGE_SIZE;
@@ -252,7 +252,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
                        continue;
                page = virt_to_page(start);
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                free_page(start);
                ++totalram_pages;
        }
@@ -640,7 +640,7 @@ mem_init (void)
 void online_page(struct page *page)
 {
        ClearPageReserved(page);
-       set_page_count(page, 1);
+       init_page_count(page);
        __free_page(page);
        totalram_pages++;
        num_physpages++;
index 6facf15..c9e7dad 100644 (file)
@@ -226,7 +226,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__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);
                totalram_pages++;
        }
@@ -244,7 +244,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        unsigned long p;
        for (p = start; p < end; p += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(p));
-               set_page_count(virt_to_page(p), 1);
+               init_page_count(virt_to_page(p));
                free_page(p);
                totalram_pages++;
        }
index c45beb9..a190e39 100644 (file)
@@ -137,7 +137,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        int pages = 0;
        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);
                totalram_pages++;
                pages++;
index 559942c..d6d582a 100644 (file)
@@ -54,7 +54,7 @@ void __init init_pointer_table(unsigned long ptable)
 
        /* unreserve the page so it's possible to free that page */
        PD_PAGE(dp)->flags &= ~(1 << PG_reserved);
-       set_page_count(PD_PAGE(dp), 1);
+       init_page_count(PD_PAGE(dp));
 
        return;
 }
index d855fec..afb57ee 100644 (file)
@@ -276,7 +276,7 @@ void free_initmem(void)
        addr = (unsigned long)&__init_begin;
        for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) {
                virt_to_page(addr)->flags &= ~(1 << PG_reserved);
-               set_page_count(virt_to_page(addr), 1);
+               init_page_count(virt_to_page(addr));
                free_page(addr);
                totalram_pages++;
        }
index 89f0b55..d79503f 100644 (file)
@@ -195,7 +195,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        int pages = 0;
        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);
                totalram_pages++;
                pages++;
@@ -218,7 +218,7 @@ free_initmem()
        /* next to check that the page we free is not a partial page */
        for (; addr + PAGE_SIZE < (unsigned long)(&__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);
                totalram_pages++;
        }
index 958d2eb..8a9ef58 100644 (file)
@@ -158,7 +158,7 @@ unsigned long __init prom_free_prom_memory(void)
                while (addr < boot_mem_map.map[i].addr
                              + boot_mem_map.map[i].size) {
                        ClearPageReserved(virt_to_page(__va(addr)));
-                       set_page_count(virt_to_page(__va(addr)), 1);
+                       init_page_count(virt_to_page(__va(addr)));
                        free_page((unsigned long)__va(addr));
                        addr += PAGE_SIZE;
                        freed += PAGE_SIZE;
index 81cb5a7..1edaf30 100644 (file)
@@ -118,7 +118,7 @@ unsigned long __init prom_free_prom_memory(void)
        addr = PAGE_SIZE;
        while (addr < end) {
                ClearPageReserved(virt_to_page(__va(addr)));
-               set_page_count(virt_to_page(__va(addr)), 1);
+               init_page_count(virt_to_page(__va(addr)));
                free_page((unsigned long)__va(addr));
                addr += PAGE_SIZE;
        }
index 2c8afd7..ee5e70c 100644 (file)
@@ -174,7 +174,7 @@ unsigned long __init prom_free_prom_memory(void)
                while (addr < boot_mem_map.map[i].addr
                              + boot_mem_map.map[i].size) {
                        ClearPageReserved(virt_to_page(__va(addr)));
-                       set_page_count(virt_to_page(__va(addr)), 1);
+                       init_page_count(virt_to_page(__va(addr)));
                        free_page((unsigned long)__va(addr));
                        addr += PAGE_SIZE;
                        freed += PAGE_SIZE;
index 0dbd743..1ec4e75 100644 (file)
@@ -117,7 +117,7 @@ unsigned long __init prom_free_prom_memory(void)
                while (addr < boot_mem_map.map[i].addr
                              + boot_mem_map.map[i].size) {
                        ClearPageReserved(virt_to_page(__va(addr)));
-                       set_page_count(virt_to_page(__va(addr)), 1);
+                       init_page_count(virt_to_page(__va(addr)));
                        free_page((unsigned long)__va(addr));
                        addr += PAGE_SIZE;
                        freed += PAGE_SIZE;
index a140da9..52f7d59 100644 (file)
@@ -245,7 +245,7 @@ void __init mem_init(void)
 #ifdef CONFIG_LIMITED_DMA
                set_page_address(page, lowmem_page_address(page));
 #endif
-               set_page_count(page, 1);
+               init_page_count(page);
                __free_page(page);
                totalhigh_pages++;
        }
@@ -292,7 +292,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
 
        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);
                totalram_pages++;
        }
@@ -315,7 +315,7 @@ void free_initmem(void)
                page = addr;
 #endif
                ClearPageReserved(virt_to_page(page));
-               set_page_count(virt_to_page(page), 1);
+               init_page_count(virt_to_page(page));
                free_page(page);
                totalram_pages++;
                freed += PAGE_SIZE;
index ed93a97..e0d095d 100644 (file)
@@ -559,7 +559,7 @@ void __init mem_init(void)
                                /* if (!page_is_ram(pgnr)) continue; */
                                /* commented out until page_is_ram works */
                                ClearPageReserved(p);
-                               set_page_count(p, 1);
+                               init_page_count(p);
                                __free_page(p);
                                totalram_pages++;
                        }
index 7847ca1..852eda3 100644 (file)
@@ -398,7 +398,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__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++;
@@ -1018,7 +1018,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                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++;
index 7d0d75c..b57fb3a 100644 (file)
@@ -216,7 +216,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
 
        while (start < end) {
                ClearPageReserved(virt_to_page(start));
-               set_page_count(virt_to_page(start), 1);
+               init_page_count(virt_to_page(start));
                free_page(start);
                cnt++;
                start += PAGE_SIZE;
@@ -248,7 +248,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                printk ("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);
                totalram_pages++;
        }
index 81cfb0c..bacb71c 100644 (file)
@@ -140,7 +140,7 @@ void free_initmem(void)
        for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
                memset((void *)addr, 0xcc, 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);
                totalram_pages++;
        }
@@ -155,7 +155,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                printk ("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);
                totalram_pages++;
        }
index 6ae5c13..454cac0 100644 (file)
@@ -108,7 +108,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
 void online_page(struct page *page)
 {
        ClearPageReserved(page);
-       set_page_count(page, 1);
+       init_page_count(page);
        __free_page(page);
        totalram_pages++;
        num_physpages++;
@@ -376,7 +376,7 @@ void __init mem_init(void)
                        struct page *page = pfn_to_page(pfn);
 
                        ClearPageReserved(page);
-                       set_page_count(page, 1);
+                       init_page_count(page);
                        __free_page(page);
                        totalhigh_pages++;
                }
index b33a444..fec8e65 100644 (file)
@@ -115,7 +115,7 @@ static void __init cell_spuprop_present(struct device_node *spe,
                for (pfn = start_pfn; pfn < end_pfn; pfn++) {
                        struct page *page = pfn_to_page(pfn);
                        set_page_links(page, ZONE_DMA, node_id, pfn);
-                       set_page_count(page, 1);
+                       init_page_count(page);
                        reset_page_mapcount(page);
                        SetPageReserved(page);
                        INIT_LIST_HEAD(&page->lru);
index 134db5c..cb1c294 100644 (file)
@@ -140,7 +140,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
 
        while (start < end) {
                ClearPageReserved(virt_to_page(start));
-               set_page_count(virt_to_page(start), 1);
+               init_page_count(virt_to_page(start));
                free_page(start);
                cnt++;
                start += PAGE_SIZE;
@@ -172,7 +172,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
 
        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);
                totalram_pages++;
        }
@@ -441,7 +441,7 @@ void __init mem_init(void)
                        struct page *page = mem_map + pfn;
 
                        ClearPageReserved(page);
-                       set_page_count(page, 1);
+                       init_page_count(page);
                        __free_page(page);
                        totalhigh_pages++;
                }
index df95338..a055894 100644 (file)
@@ -292,7 +292,7 @@ void free_initmem(void)
         addr = (unsigned long)(&__init_begin);
         for (; addr < (unsigned long)(&__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);
                totalram_pages++;
         }
@@ -307,7 +307,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                 printk ("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);
                 totalram_pages++;
         }
index e342565..77b4a83 100644 (file)
@@ -273,7 +273,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__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);
                totalram_pages++;
        }
@@ -286,7 +286,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        unsigned long p;
        for (p = start; p < end; p += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(p));
-               set_page_count(virt_to_page(p), 1);
+               init_page_count(virt_to_page(p));
                free_page(p);
                totalram_pages++;
        }
index a65e8bb..1169757 100644 (file)
@@ -173,7 +173,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__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);
                totalram_pages++;
        }
@@ -186,7 +186,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        unsigned long p;
        for (p = start; p < end; p += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(p));
-               set_page_count(virt_to_page(p), 1);
+               init_page_count(virt_to_page(p));
                free_page(p);
                totalram_pages++;
        }
index 40d426c..4219dd2 100644 (file)
@@ -266,19 +266,19 @@ void __init smp4d_boot_cpus(void)
 
        /* Free unneeded trap tables */
        ClearPageReserved(virt_to_page(trapbase_cpu1));
-       set_page_count(virt_to_page(trapbase_cpu1), 1);
+       init_page_count(virt_to_page(trapbase_cpu1));
        free_page((unsigned long)trapbase_cpu1);
        totalram_pages++;
        num_physpages++;
 
        ClearPageReserved(virt_to_page(trapbase_cpu2));
-       set_page_count(virt_to_page(trapbase_cpu2), 1);
+       init_page_count(virt_to_page(trapbase_cpu2));
        free_page((unsigned long)trapbase_cpu2);
        totalram_pages++;
        num_physpages++;
 
        ClearPageReserved(virt_to_page(trapbase_cpu3));
-       set_page_count(virt_to_page(trapbase_cpu3), 1);
+       init_page_count(virt_to_page(trapbase_cpu3));
        free_page((unsigned long)trapbase_cpu3);
        totalram_pages++;
        num_physpages++;
index a21f27d..fbbd8a4 100644 (file)
@@ -233,21 +233,21 @@ void __init smp4m_boot_cpus(void)
        /* Free unneeded trap tables */
        if (!cpu_isset(i, cpu_present_map)) {
                ClearPageReserved(virt_to_page(trapbase_cpu1));
-               set_page_count(virt_to_page(trapbase_cpu1), 1);
+               init_page_count(virt_to_page(trapbase_cpu1));
                free_page((unsigned long)trapbase_cpu1);
                totalram_pages++;
                num_physpages++;
        }
        if (!cpu_isset(2, cpu_present_map)) {
                ClearPageReserved(virt_to_page(trapbase_cpu2));
-               set_page_count(virt_to_page(trapbase_cpu2), 1);
+               init_page_count(virt_to_page(trapbase_cpu2));
                free_page((unsigned long)trapbase_cpu2);
                totalram_pages++;
                num_physpages++;
        }
        if (!cpu_isset(3, cpu_present_map)) {
                ClearPageReserved(virt_to_page(trapbase_cpu3));
-               set_page_count(virt_to_page(trapbase_cpu3), 1);
+               init_page_count(virt_to_page(trapbase_cpu3));
                free_page((unsigned long)trapbase_cpu3);
                totalram_pages++;
                num_physpages++;
index c03baba..8986697 100644 (file)
@@ -383,7 +383,7 @@ void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
                struct page *page = pfn_to_page(tmp);
 
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                __free_page(page);
                totalhigh_pages++;
        }
@@ -480,7 +480,7 @@ void free_initmem (void)
                p = virt_to_page(addr);
 
                ClearPageReserved(p);
-               set_page_count(p, 1);
+               init_page_count(p);
                __free_page(p);
                totalram_pages++;
                num_physpages++;
@@ -497,7 +497,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                struct page *p = virt_to_page(start);
 
                ClearPageReserved(p);
-               set_page_count(p, 1);
+               init_page_count(p);
                __free_page(p);
                num_physpages++;
        }
index c2b5561..2ae143b 100644 (file)
@@ -1461,7 +1461,7 @@ void free_initmem(void)
                p = virt_to_page(page);
 
                ClearPageReserved(p);
-               set_page_count(p, 1);
+               init_page_count(p);
                __free_page(p);
                num_physpages++;
                totalram_pages++;
@@ -1477,7 +1477,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                struct page *p = virt_to_page(start);
 
                ClearPageReserved(p);
-               set_page_count(p, 1);
+               init_page_count(p);
                __free_page(p);
                num_physpages++;
                totalram_pages++;
index fa4f915..92cce96 100644 (file)
@@ -57,7 +57,7 @@ static void setup_highmem(unsigned long highmem_start,
        for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
                page = &mem_map[highmem_pfn + i];
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                __free_page(page);
        }
 }
@@ -296,7 +296,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                        (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);
                totalram_pages++;
        }
index 7af1742..40ed13d 100644 (file)
@@ -486,7 +486,7 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size)
 void online_page(struct page *page)
 {
        ClearPageReserved(page);
-       set_page_count(page, 1);
+       init_page_count(page);
        __free_page(page);
        totalram_pages++;
        num_physpages++;
@@ -592,7 +592,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__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));
                memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); 
                free_page(addr);
                totalram_pages++;
@@ -632,7 +632,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        printk ("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);
                totalram_pages++;
        }
index 5a91d6c..e1be423 100644 (file)
@@ -272,7 +272,7 @@ free_reserved_mem(void *start, void *end)
 {
        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((unsigned long)start);
                totalram_pages++;
        }
index b058273..76448d6 100644 (file)
@@ -1269,7 +1269,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
                 */
                page = virt_to_page(virtual_start);
                ClearPageReserved(page);
-               set_page_count(page, 1);
+               init_page_count(page);
                free_page(virtual_start);
 
                virtual_start += PAGE_SIZE;
index 3d84b7a..7d8c127 100644 (file)
@@ -307,8 +307,6 @@ static inline int get_page_unless_zero(struct page *page)
        return atomic_inc_not_zero(&page->_count);
 }
 
-#define set_page_count(p,v)    atomic_set(&(p)->_count, (v))
-
 extern void FASTCALL(__page_cache_release(struct page *));
 
 static inline int page_count(struct page *page)
@@ -325,6 +323,15 @@ static inline void get_page(struct page *page)
        atomic_inc(&page->_count);
 }
 
+/*
+ * Setup the page count before being freed into the page allocator for
+ * the first time (boot or memory hotplug)
+ */
+static inline void init_page_count(struct page *page)
+{
+       atomic_set(&page->_count, 1);
+}
+
 void put_page(struct page *page);
 
 void split_page(struct page *page, unsigned int order);
index 39d49ec..20117a4 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/pgtable.h>
 
 #include <linux/hugetlb.h>
+#include "internal.h"
 
 const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
 static unsigned long nr_huge_pages, free_huge_pages;
@@ -106,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr)
                return NULL;
        }
        spin_unlock(&hugetlb_lock);
-       set_page_count(page, 1);
+       set_page_refcounted(page);
        for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
                clear_user_highpage(&page[i], addr);
        return page;
@@ -152,7 +153,7 @@ static void update_and_free_page(struct page *page)
                                1 << PG_private | 1<< PG_writeback);
        }
        page[1].lru.next = NULL;
-       set_page_count(page, 1);
+       set_page_refcounted(page);
        __free_pages(page, HUGETLB_PAGE_ORDER);
 }
 
index 7bb3397..d20e3cc 100644 (file)
 
 #include <linux/mm.h>
 
-static inline void set_page_refs(struct page *page, int order)
+static inline void set_page_count(struct page *page, int v)
 {
+       atomic_set(&page->_count, v);
+}
+
+/*
+ * Turn a non-refcounted page (->_count == 0) into refcounted with
+ * a count of one.
+ */
+static inline void set_page_refcounted(struct page *page)
+{
+       BUG_ON(PageCompound(page) && page_private(page) != (unsigned long)page);
+       BUG_ON(atomic_read(&page->_count));
        set_page_count(page, 1);
 }
 
index e197818..7f65b5a 100644 (file)
@@ -442,7 +442,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
        if (order == 0) {
                __ClearPageReserved(page);
                set_page_count(page, 0);
-               set_page_refs(page, 0);
+               set_page_refcounted(page);
                __free_page(page);
        } else {
                int loop;
@@ -457,7 +457,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
                        set_page_count(p, 0);
                }
 
-               set_page_refs(page, order);
+               set_page_refcounted(page);
                __free_pages(page, order);
        }
 }
@@ -525,7 +525,7 @@ static int prep_new_page(struct page *page, int order)
                        1 << PG_referenced | 1 << PG_arch_1 |
                        1 << PG_checked | 1 << PG_mappedtodisk);
        set_page_private(page, 0);
-       set_page_refs(page, order);
+       set_page_refcounted(page);
        kernel_map_pages(page, 1 << order, 1);
        return 0;
 }
@@ -755,10 +755,8 @@ void split_page(struct page *page, unsigned int order)
 
        BUG_ON(PageCompound(page));
        BUG_ON(!page_count(page));
-       for (i = 1; i < (1 << order); i++) {
-               BUG_ON(page_count(page + i));
-               set_page_count(page + i, 1);
-       }
+       for (i = 1; i < (1 << order); i++)
+               set_page_refcounted(page + i);
 }
 
 /*
@@ -1771,7 +1769,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
                        continue;
                page = pfn_to_page(pfn);
                set_page_links(page, zone, nid, pfn);
-               set_page_count(page, 1);
+               init_page_count(page);
                reset_page_mapcount(page);
                SetPageReserved(page);
                INIT_LIST_HEAD(&page->lru);