Commit 7835e98b authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

[PATCH] remove set_page_count() outside mm/

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: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 70dc991d
...@@ -357,7 +357,7 @@ free_reserved_mem(void *start, void *end) ...@@ -357,7 +357,7 @@ free_reserved_mem(void *start, void *end)
void *__start = start; void *__start = start;
for (; __start < end; __start += PAGE_SIZE) { for (; __start < end; __start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(__start)); ClearPageReserved(virt_to_page(__start));
set_page_count(virt_to_page(__start), 1); init_page_count(virt_to_page(__start));
free_page((long)__start); free_page((long)__start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -531,7 +531,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) ...@@ -531,7 +531,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
for (; addr < end; addr += PAGE_SIZE) { for (; addr < end; addr += PAGE_SIZE) {
struct page *page = virt_to_page(addr); struct page *page = virt_to_page(addr);
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
......
...@@ -324,7 +324,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) ...@@ -324,7 +324,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
for (; addr < end; addr += PAGE_SIZE) { for (; addr < end; addr += PAGE_SIZE) {
struct page *page = virt_to_page(addr); struct page *page = virt_to_page(addr);
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
......
...@@ -216,7 +216,7 @@ free_initmem(void) ...@@ -216,7 +216,7 @@ free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
......
...@@ -169,7 +169,7 @@ void __init mem_init(void) ...@@ -169,7 +169,7 @@ void __init mem_init(void)
struct page *page = &mem_map[pfn]; struct page *page = &mem_map[pfn];
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalram_pages++; totalram_pages++;
} }
...@@ -210,7 +210,7 @@ void __init free_initmem(void) ...@@ -210,7 +210,7 @@ void __init free_initmem(void)
/* next to check that the page we free is not a partial page */ /* next to check that the page we free is not a partial page */
for (addr = start; addr < end; addr += PAGE_SIZE) { for (addr = start; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -230,7 +230,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) ...@@ -230,7 +230,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
int pages = 0; int pages = 0;
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
pages++; pages++;
......
...@@ -196,7 +196,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -196,7 +196,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
int pages = 0; int pages = 0;
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
pages++; pages++;
...@@ -219,7 +219,7 @@ free_initmem() ...@@ -219,7 +219,7 @@ free_initmem()
/* next to check that the page we free is not a partial page */ /* next to check that the page we free is not a partial page */
for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
......
...@@ -270,7 +270,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base) ...@@ -270,7 +270,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
static void __meminit free_new_highpage(struct page *page) static void __meminit free_new_highpage(struct page *page)
{ {
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalhigh_pages++; totalhigh_pages++;
} }
...@@ -727,7 +727,7 @@ void free_initmem(void) ...@@ -727,7 +727,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); 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); memset((void *)addr, 0xcc, PAGE_SIZE);
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
...@@ -766,7 +766,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -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); printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -197,7 +197,7 @@ free_initmem (void) ...@@ -197,7 +197,7 @@ free_initmem (void)
eaddr = (unsigned long) ia64_imva(__init_end); eaddr = (unsigned long) ia64_imva(__init_end);
while (addr < eaddr) { while (addr < eaddr) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
++totalram_pages; ++totalram_pages;
addr += PAGE_SIZE; addr += PAGE_SIZE;
...@@ -252,7 +252,7 @@ free_initrd_mem (unsigned long start, unsigned long end) ...@@ -252,7 +252,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
continue; continue;
page = virt_to_page(start); page = virt_to_page(start);
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
free_page(start); free_page(start);
++totalram_pages; ++totalram_pages;
} }
...@@ -640,7 +640,7 @@ mem_init (void) ...@@ -640,7 +640,7 @@ mem_init (void)
void online_page(struct page *page) void online_page(struct page *page)
{ {
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
......
...@@ -226,7 +226,7 @@ void free_initmem(void) ...@@ -226,7 +226,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -244,7 +244,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -244,7 +244,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
unsigned long p; unsigned long p;
for (p = start; p < end; p += PAGE_SIZE) { for (p = start; p < end; p += PAGE_SIZE) {
ClearPageReserved(virt_to_page(p)); ClearPageReserved(virt_to_page(p));
set_page_count(virt_to_page(p), 1); init_page_count(virt_to_page(p));
free_page(p); free_page(p);
totalram_pages++; totalram_pages++;
} }
......
...@@ -137,7 +137,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -137,7 +137,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
int pages = 0; int pages = 0;
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
pages++; pages++;
......
...@@ -54,7 +54,7 @@ void __init init_pointer_table(unsigned long ptable) ...@@ -54,7 +54,7 @@ void __init init_pointer_table(unsigned long ptable)
/* unreserve the page so it's possible to free that page */ /* unreserve the page so it's possible to free that page */
PD_PAGE(dp)->flags &= ~(1 << PG_reserved); PD_PAGE(dp)->flags &= ~(1 << PG_reserved);
set_page_count(PD_PAGE(dp), 1); init_page_count(PD_PAGE(dp));
return; return;
} }
......
...@@ -276,7 +276,7 @@ void free_initmem(void) ...@@ -276,7 +276,7 @@ void free_initmem(void)
addr = (unsigned long)&__init_begin; addr = (unsigned long)&__init_begin;
for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) { for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) {
virt_to_page(addr)->flags &= ~(1 << PG_reserved); 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); free_page(addr);
totalram_pages++; totalram_pages++;
} }
......
...@@ -195,7 +195,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -195,7 +195,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
int pages = 0; int pages = 0;
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
pages++; pages++;
...@@ -218,7 +218,7 @@ free_initmem() ...@@ -218,7 +218,7 @@ free_initmem()
/* next to check that the page we free is not a partial page */ /* next to check that the page we free is not a partial page */
for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
......
...@@ -158,7 +158,7 @@ unsigned long __init prom_free_prom_memory(void) ...@@ -158,7 +158,7 @@ unsigned long __init prom_free_prom_memory(void)
while (addr < boot_mem_map.map[i].addr while (addr < boot_mem_map.map[i].addr
+ boot_mem_map.map[i].size) { + boot_mem_map.map[i].size) {
ClearPageReserved(virt_to_page(__va(addr))); 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)); free_page((unsigned long)__va(addr));
addr += PAGE_SIZE; addr += PAGE_SIZE;
freed += PAGE_SIZE; freed += PAGE_SIZE;
......
...@@ -118,7 +118,7 @@ unsigned long __init prom_free_prom_memory(void) ...@@ -118,7 +118,7 @@ unsigned long __init prom_free_prom_memory(void)
addr = PAGE_SIZE; addr = PAGE_SIZE;
while (addr < end) { while (addr < end) {
ClearPageReserved(virt_to_page(__va(addr))); 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)); free_page((unsigned long)__va(addr));
addr += PAGE_SIZE; addr += PAGE_SIZE;
} }
......
...@@ -174,7 +174,7 @@ unsigned long __init prom_free_prom_memory(void) ...@@ -174,7 +174,7 @@ unsigned long __init prom_free_prom_memory(void)
while (addr < boot_mem_map.map[i].addr while (addr < boot_mem_map.map[i].addr
+ boot_mem_map.map[i].size) { + boot_mem_map.map[i].size) {
ClearPageReserved(virt_to_page(__va(addr))); 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)); free_page((unsigned long)__va(addr));
addr += PAGE_SIZE; addr += PAGE_SIZE;
freed += PAGE_SIZE; freed += PAGE_SIZE;
......
...@@ -117,7 +117,7 @@ unsigned long __init prom_free_prom_memory(void) ...@@ -117,7 +117,7 @@ unsigned long __init prom_free_prom_memory(void)
while (addr < boot_mem_map.map[i].addr while (addr < boot_mem_map.map[i].addr
+ boot_mem_map.map[i].size) { + boot_mem_map.map[i].size) {
ClearPageReserved(virt_to_page(__va(addr))); 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)); free_page((unsigned long)__va(addr));
addr += PAGE_SIZE; addr += PAGE_SIZE;
freed += PAGE_SIZE; freed += PAGE_SIZE;
......
...@@ -245,7 +245,7 @@ void __init mem_init(void) ...@@ -245,7 +245,7 @@ void __init mem_init(void)
#ifdef CONFIG_LIMITED_DMA #ifdef CONFIG_LIMITED_DMA
set_page_address(page, lowmem_page_address(page)); set_page_address(page, lowmem_page_address(page));
#endif #endif
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalhigh_pages++; totalhigh_pages++;
} }
...@@ -292,7 +292,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -292,7 +292,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
...@@ -315,7 +315,7 @@ void free_initmem(void) ...@@ -315,7 +315,7 @@ void free_initmem(void)
page = addr; page = addr;
#endif #endif
ClearPageReserved(virt_to_page(page)); ClearPageReserved(virt_to_page(page));
set_page_count(virt_to_page(page), 1); init_page_count(virt_to_page(page));
free_page(page); free_page(page);
totalram_pages++; totalram_pages++;
freed += PAGE_SIZE; freed += PAGE_SIZE;
......
...@@ -559,7 +559,7 @@ void __init mem_init(void) ...@@ -559,7 +559,7 @@ void __init mem_init(void)
/* if (!page_is_ram(pgnr)) continue; */ /* if (!page_is_ram(pgnr)) continue; */
/* commented out until page_is_ram works */ /* commented out until page_is_ram works */
ClearPageReserved(p); ClearPageReserved(p);
set_page_count(p, 1); init_page_count(p);
__free_page(p); __free_page(p);
totalram_pages++; totalram_pages++;
} }
......
...@@ -398,7 +398,7 @@ void free_initmem(void) ...@@ -398,7 +398,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
num_physpages++; num_physpages++;
totalram_pages++; totalram_pages++;
...@@ -1018,7 +1018,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -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); printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
num_physpages++; num_physpages++;
totalram_pages++; totalram_pages++;
......
...@@ -216,7 +216,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name) ...@@ -216,7 +216,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
while (start < end) { while (start < end) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
cnt++; cnt++;
start += PAGE_SIZE; start += PAGE_SIZE;
...@@ -248,7 +248,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -248,7 +248,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -140,7 +140,7 @@ void free_initmem(void) ...@@ -140,7 +140,7 @@ void free_initmem(void)
for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
memset((void *)addr, 0xcc, PAGE_SIZE); memset((void *)addr, 0xcc, PAGE_SIZE);
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -155,7 +155,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -155,7 +155,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -108,7 +108,7 @@ EXPORT_SYMBOL(phys_mem_access_prot); ...@@ -108,7 +108,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
void online_page(struct page *page) void online_page(struct page *page)
{ {
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
...@@ -376,7 +376,7 @@ void __init mem_init(void) ...@@ -376,7 +376,7 @@ void __init mem_init(void)
struct page *page = pfn_to_page(pfn); struct page *page = pfn_to_page(pfn);
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalhigh_pages++; totalhigh_pages++;
} }
......
...@@ -115,7 +115,7 @@ static void __init cell_spuprop_present(struct device_node *spe, ...@@ -115,7 +115,7 @@ static void __init cell_spuprop_present(struct device_node *spe,
for (pfn = start_pfn; pfn < end_pfn; pfn++) { for (pfn = start_pfn; pfn < end_pfn; pfn++) {
struct page *page = pfn_to_page(pfn); struct page *page = pfn_to_page(pfn);
set_page_links(page, ZONE_DMA, node_id, pfn); set_page_links(page, ZONE_DMA, node_id, pfn);
set_page_count(page, 1); init_page_count(page);
reset_page_mapcount(page); reset_page_mapcount(page);
SetPageReserved(page); SetPageReserved(page);
INIT_LIST_HEAD(&page->lru); INIT_LIST_HEAD(&page->lru);
......
...@@ -140,7 +140,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name) ...@@ -140,7 +140,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
while (start < end) { while (start < end) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
cnt++; cnt++;
start += PAGE_SIZE; start += PAGE_SIZE;
...@@ -172,7 +172,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -172,7 +172,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
...@@ -441,7 +441,7 @@ void __init mem_init(void) ...@@ -441,7 +441,7 @@ void __init mem_init(void)
struct page *page = mem_map + pfn; struct page *page = mem_map + pfn;
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalhigh_pages++; totalhigh_pages++;
} }
......
...@@ -292,7 +292,7 @@ void free_initmem(void) ...@@ -292,7 +292,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -307,7 +307,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -307,7 +307,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -273,7 +273,7 @@ void free_initmem(void) ...@@ -273,7 +273,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -286,7 +286,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -286,7 +286,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
unsigned long p; unsigned long p;
for (p = start; p < end; p += PAGE_SIZE) { for (p = start; p < end; p += PAGE_SIZE) {
ClearPageReserved(virt_to_page(p)); ClearPageReserved(virt_to_page(p));
set_page_count(virt_to_page(p), 1); init_page_count(virt_to_page(p));
free_page(p); free_page(p);
totalram_pages++; totalram_pages++;
} }
......
...@@ -173,7 +173,7 @@ void free_initmem(void) ...@@ -173,7 +173,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1); init_page_count(virt_to_page(addr));
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -186,7 +186,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -186,7 +186,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
unsigned long p; unsigned long p;
for (p = start; p < end; p += PAGE_SIZE) { for (p = start; p < end; p += PAGE_SIZE) {
ClearPageReserved(virt_to_page(p)); ClearPageReserved(virt_to_page(p));
set_page_count(virt_to_page(p), 1); init_page_count(virt_to_page(p));
free_page(p); free_page(p);
totalram_pages++; totalram_pages++;
} }
......
...@@ -266,19 +266,19 @@ void __init smp4d_boot_cpus(void) ...@@ -266,19 +266,19 @@ void __init smp4d_boot_cpus(void)
/* Free unneeded trap tables */ /* Free unneeded trap tables */
ClearPageReserved(virt_to_page(trapbase_cpu1)); 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); free_page((unsigned long)trapbase_cpu1);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
ClearPageReserved(virt_to_page(trapbase_cpu2)); 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); free_page((unsigned long)trapbase_cpu2);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
ClearPageReserved(virt_to_page(trapbase_cpu3)); 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); free_page((unsigned long)trapbase_cpu3);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
......
...@@ -233,21 +233,21 @@ void __init smp4m_boot_cpus(void) ...@@ -233,21 +233,21 @@ void __init smp4m_boot_cpus(void)
/* Free unneeded trap tables */ /* Free unneeded trap tables */
if (!cpu_isset(i, cpu_present_map)) { if (!cpu_isset(i, cpu_present_map)) {
ClearPageReserved(virt_to_page(trapbase_cpu1)); 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); free_page((unsigned long)trapbase_cpu1);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
} }
if (!cpu_isset(2, cpu_present_map)) { if (!cpu_isset(2, cpu_present_map)) {
ClearPageReserved(virt_to_page(trapbase_cpu2)); 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); free_page((unsigned long)trapbase_cpu2);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
} }
if (!cpu_isset(3, cpu_present_map)) { if (!cpu_isset(3, cpu_present_map)) {
ClearPageReserved(virt_to_page(trapbase_cpu3)); 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); free_page((unsigned long)trapbase_cpu3);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
......
...@@ -383,7 +383,7 @@ void map_high_region(unsigned long start_pfn, unsigned long end_pfn) ...@@ -383,7 +383,7 @@ void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
struct page *page = pfn_to_page(tmp); struct page *page = pfn_to_page(tmp);
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalhigh_pages++; totalhigh_pages++;
} }
...@@ -480,7 +480,7 @@ void free_initmem (void) ...@@ -480,7 +480,7 @@ void free_initmem (void)
p = virt_to_page(addr); p = virt_to_page(addr);
ClearPageReserved(p); ClearPageReserved(p);
set_page_count(p, 1); init_page_count(p);
__free_page(p); __free_page(p);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
...@@ -497,7 +497,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -497,7 +497,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
struct page *p = virt_to_page(start); struct page *p = virt_to_page(start);
ClearPageReserved(p); ClearPageReserved(p);
set_page_count(p, 1); init_page_count(p);
__free_page(p); __free_page(p);
num_physpages++; num_physpages++;
} }
......
...@@ -1461,7 +1461,7 @@ void free_initmem(void) ...@@ -1461,7 +1461,7 @@ void free_initmem(void)
p = virt_to_page(page); p = virt_to_page(page);
ClearPageReserved(p); ClearPageReserved(p);
set_page_count(p, 1); init_page_count(p);
__free_page(p); __free_page(p);
num_physpages++; num_physpages++;
totalram_pages++; totalram_pages++;
...@@ -1477,7 +1477,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -1477,7 +1477,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
struct page *p = virt_to_page(start); struct page *p = virt_to_page(start);
ClearPageReserved(p); ClearPageReserved(p);
set_page_count(p, 1); init_page_count(p);
__free_page(p); __free_page(p);
num_physpages++; num_physpages++;
totalram_pages++; totalram_pages++;
......
...@@ -57,7 +57,7 @@ static void setup_highmem(unsigned long highmem_start, ...@@ -57,7 +57,7 @@ static void setup_highmem(unsigned long highmem_start,
for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){ for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
page = &mem_map[highmem_pfn + i]; page = &mem_map[highmem_pfn + i];
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
} }
} }
...@@ -296,7 +296,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -296,7 +296,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
(end - start) >> 10); (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -486,7 +486,7 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) ...@@ -486,7 +486,7 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size)
void online_page(struct page *page) void online_page(struct page *page)
{ {
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
__free_page(page); __free_page(page);
totalram_pages++; totalram_pages++;
num_physpages++; num_physpages++;
...@@ -592,7 +592,7 @@ void free_initmem(void) ...@@ -592,7 +592,7 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin); addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); 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); memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE);
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
...@@ -632,7 +632,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -632,7 +632,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1); init_page_count(virt_to_page(start));
free_page(start); free_page(start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -272,7 +272,7 @@ free_reserved_mem(void *start, void *end) ...@@ -272,7 +272,7 @@ free_reserved_mem(void *start, void *end)
{ {
for (; start < end; start += PAGE_SIZE) { for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start)); 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); free_page((unsigned long)start);
totalram_pages++; totalram_pages++;
} }
......
...@@ -1269,7 +1269,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) ...@@ -1269,7 +1269,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
*/ */
page = virt_to_page(virtual_start); page = virt_to_page(virtual_start);
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); init_page_count(page);
free_page(virtual_start); free_page(virtual_start);
virtual_start += PAGE_SIZE; virtual_start += PAGE_SIZE;
......
...@@ -307,8 +307,6 @@ static inline int get_page_unless_zero(struct page *page) ...@@ -307,8 +307,6 @@ static inline int get_page_unless_zero(struct page *page)
return atomic_inc_not_zero(&page->_count); 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 *)); extern void FASTCALL(__page_cache_release(struct page *));
static inline int page_count(struct page *page) static inline int page_count(struct page *page)
...@@ -325,6 +323,15 @@ static inline void get_page(struct page *page) ...@@ -325,6 +323,15 @@ static inline void get_page(struct page *page)
atomic_inc(&page->_count); 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 put_page(struct page *page);
void split_page(struct page *page, unsigned int order); void split_page(struct page *page, unsigned int order);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include "internal.h"
const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
static unsigned long nr_huge_pages, free_huge_pages; 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) ...@@ -106,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr)
return NULL; return NULL;
} }
spin_unlock(&hugetlb_lock); spin_unlock(&hugetlb_lock);
set_page_count(page, 1); set_page_refcounted(page);
for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
clear_user_highpage(&page[i], addr); clear_user_highpage(&page[i], addr);
return page; return page;
...@@ -152,7 +153,7 @@ static void update_and_free_page(struct page *page) ...@@ -152,7 +153,7 @@ static void update_and_free_page(struct page *page)
1 << PG_private | 1<< PG_writeback); 1 << PG_private | 1<< PG_writeback);
} }
page[1].lru.next = NULL; page[1].lru.next = NULL;
set_page_count(page, 1); set_page_refcounted(page);
__free_pages(page, HUGETLB_PAGE_ORDER); __free_pages(page, HUGETLB_PAGE_ORDER);
} }
......
...@@ -13,8 +13,19 @@ ...@@ -13,8 +13,19 @@
#include <linux/mm.h> #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); set_page_count(page, 1);
} }
......
...@@ -442,7 +442,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order) ...@@ -442,7 +442,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
if (order == 0) { if (order == 0) {
__ClearPageReserved(page); __ClearPageReserved(page);
set_page_count(page, 0); set_page_count(page, 0);
set_page_refs(page, 0); set_page_refcounted(page);
__free_page(page); __free_page(page);
} else { } else {
int loop; int loop;
...@@ -457,7 +457,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order) ...@@ -457,7 +457,7 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
set_page_count(p, 0); set_page_count(p, 0);
} }
set_page_refs(page, order); set_page_refcounted(page);
__free_pages(page, order); __free_pages(page, order);
} }
} }
...@@ -525,7 +525,7 @@ static int prep_new_page(struct page *page, int order) ...@@ -525,7 +525,7 @@ static int prep_new_page(struct page *page, int order)
1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_referenced | 1 << PG_arch_1 |
1 << PG_checked | 1 << PG_mappedtodisk); 1 << PG_checked | 1 << PG_mappedtodisk);
set_page_private(page, 0); set_page_private(page, 0);
set_page_refs(page, order); set_page_refcounted(page);
kernel_map_pages(page, 1 << order, 1); kernel_map_pages(page, 1 << order, 1);
return 0; return 0;
} }
...@@ -755,10 +755,8 @@ void split_page(struct page *page, unsigned int order) ...@@ -755,10 +755,8 @@ void split_page(struct page *page, unsigned int order)
BUG_ON(PageCompound(page)); BUG_ON(PageCompound(page));
BUG_ON(!page_count(page)); BUG_ON(!page_count(page));
for (i = 1; i < (1 << order); i++) { for (i = 1; i < (1 << order); i++)
BUG_ON(page_count(page + i)); set_page_refcounted(page + i);
set_page_count(page + i, 1);
}
} }
/* /*
...@@ -1771,7 +1769,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, ...@@ -1771,7 +1769,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
continue; continue;
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
set_page_links(page, zone, nid, pfn); set_page_links(page, zone, nid, pfn);
set_page_count(page, 1); init_page_count(page);
reset_page_mapcount(page); reset_page_mapcount(page);
SetPageReserved(page); SetPageReserved(page);
INIT_LIST_HEAD(&page->lru); INIT_LIST_HEAD(&page->lru);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment