diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a8c003e7b3d5..bf2f6cff1d6a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/stop_machine.h> | 39 | #include <linux/stop_machine.h> |
40 | #include <linux/sort.h> | 40 | #include <linux/sort.h> |
41 | #include <linux/pfn.h> | 41 | #include <linux/pfn.h> |
42 | #include <linux/backing-dev.h> | ||
42 | 43 | ||
43 | #include <asm/tlbflush.h> | 44 | #include <asm/tlbflush.h> |
44 | #include <asm/div64.h> | 45 | #include <asm/div64.h> |
@@ -495,17 +496,16 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
495 | int i; | 496 | int i; |
496 | int reserved = 0; | 497 | int reserved = 0; |
497 | 498 | ||
498 | arch_free_page(page, order); | ||
499 | if (!PageHighMem(page)) | ||
500 | debug_check_no_locks_freed(page_address(page), | ||
501 | PAGE_SIZE<<order); | ||
502 | |||
503 | for (i = 0 ; i < (1 << order) ; ++i) | 499 | for (i = 0 ; i < (1 << order) ; ++i) |
504 | reserved += free_pages_check(page + i); | 500 | reserved += free_pages_check(page + i); |
505 | if (reserved) | 501 | if (reserved) |
506 | return; | 502 | return; |
507 | 503 | ||
504 | if (!PageHighMem(page)) | ||
505 | debug_check_no_locks_freed(page_address(page),PAGE_SIZE<<order); | ||
506 | arch_free_page(page, order); | ||
508 | kernel_map_pages(page, 1 << order, 0); | 507 | kernel_map_pages(page, 1 << order, 0); |
508 | |||
509 | local_irq_save(flags); | 509 | local_irq_save(flags); |
510 | __count_vm_events(PGFREE, 1 << order); | 510 | __count_vm_events(PGFREE, 1 << order); |
511 | free_one_page(page_zone(page), page, order); | 511 | free_one_page(page_zone(page), page, order); |
@@ -781,13 +781,14 @@ static void fastcall free_hot_cold_page(struct page *page, int cold) | |||
781 | struct per_cpu_pages *pcp; | 781 | struct per_cpu_pages *pcp; |
782 | unsigned long flags; | 782 | unsigned long flags; |
783 | 783 | ||
784 | arch_free_page(page, 0); | ||
785 | |||
786 | if (PageAnon(page)) | 784 | if (PageAnon(page)) |
787 | page->mapping = NULL; | 785 | page->mapping = NULL; |
788 | if (free_pages_check(page)) | 786 | if (free_pages_check(page)) |
789 | return; | 787 | return; |
790 | 788 | ||
789 | if (!PageHighMem(page)) | ||
790 | debug_check_no_locks_freed(page_address(page), PAGE_SIZE); | ||
791 | arch_free_page(page, 0); | ||
791 | kernel_map_pages(page, 1, 0); | 792 | kernel_map_pages(page, 1, 0); |
792 | 793 | ||
793 | pcp = &zone_pcp(zone, get_cpu())->pcp[cold]; | 794 | pcp = &zone_pcp(zone, get_cpu())->pcp[cold]; |
@@ -852,7 +853,7 @@ again: | |||
852 | pcp = &zone_pcp(zone, cpu)->pcp[cold]; | 853 | pcp = &zone_pcp(zone, cpu)->pcp[cold]; |
853 | local_irq_save(flags); | 854 | local_irq_save(flags); |
854 | if (!pcp->count) { | 855 | if (!pcp->count) { |
855 | pcp->count += rmqueue_bulk(zone, 0, | 856 | pcp->count = rmqueue_bulk(zone, 0, |
856 | pcp->batch, &pcp->list); | 857 | pcp->batch, &pcp->list); |
857 | if (unlikely(!pcp->count)) | 858 | if (unlikely(!pcp->count)) |
858 | goto failed; | 859 | goto failed; |
@@ -1050,7 +1051,7 @@ nofail_alloc: | |||
1050 | if (page) | 1051 | if (page) |
1051 | goto got_pg; | 1052 | goto got_pg; |
1052 | if (gfp_mask & __GFP_NOFAIL) { | 1053 | if (gfp_mask & __GFP_NOFAIL) { |
1053 | blk_congestion_wait(WRITE, HZ/50); | 1054 | congestion_wait(WRITE, HZ/50); |
1054 | goto nofail_alloc; | 1055 | goto nofail_alloc; |
1055 | } | 1056 | } |
1056 | } | 1057 | } |
@@ -1113,7 +1114,7 @@ rebalance: | |||
1113 | do_retry = 1; | 1114 | do_retry = 1; |
1114 | } | 1115 | } |
1115 | if (do_retry) { | 1116 | if (do_retry) { |
1116 | blk_congestion_wait(WRITE, HZ/50); | 1117 | congestion_wait(WRITE, HZ/50); |
1117 | goto rebalance; | 1118 | goto rebalance; |
1118 | } | 1119 | } |
1119 | 1120 | ||
@@ -1688,6 +1689,8 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, | |||
1688 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | 1689 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { |
1689 | if (!early_pfn_valid(pfn)) | 1690 | if (!early_pfn_valid(pfn)) |
1690 | continue; | 1691 | continue; |
1692 | if (!early_pfn_in_nid(pfn, nid)) | ||
1693 | continue; | ||
1691 | page = pfn_to_page(pfn); | 1694 | page = pfn_to_page(pfn); |
1692 | set_page_links(page, zone, nid, pfn); | 1695 | set_page_links(page, zone, nid, pfn); |
1693 | init_page_count(page); | 1696 | init_page_count(page); |
@@ -2258,7 +2261,7 @@ unsigned long __init __absent_pages_in_range(int nid, | |||
2258 | 2261 | ||
2259 | /* Account for ranges past physical memory on this node */ | 2262 | /* Account for ranges past physical memory on this node */ |
2260 | if (range_end_pfn > prev_end_pfn) | 2263 | if (range_end_pfn > prev_end_pfn) |
2261 | hole_pages = range_end_pfn - | 2264 | hole_pages += range_end_pfn - |
2262 | max(range_start_pfn, prev_end_pfn); | 2265 | max(range_start_pfn, prev_end_pfn); |
2263 | 2266 | ||
2264 | return hole_pages; | 2267 | return hole_pages; |
@@ -2294,19 +2297,6 @@ unsigned long __init zone_absent_pages_in_node(int nid, | |||
2294 | return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn); | 2297 | return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn); |
2295 | } | 2298 | } |
2296 | 2299 | ||
2297 | /* Return the zone index a PFN is in */ | ||
2298 | int memmap_zone_idx(struct page *lmem_map) | ||
2299 | { | ||
2300 | int i; | ||
2301 | unsigned long phys_addr = virt_to_phys(lmem_map); | ||
2302 | unsigned long pfn = phys_addr >> PAGE_SHIFT; | ||
2303 | |||
2304 | for (i = 0; i < MAX_NR_ZONES; i++) | ||
2305 | if (pfn < arch_zone_highest_possible_pfn[i]) | ||
2306 | break; | ||
2307 | |||
2308 | return i; | ||
2309 | } | ||
2310 | #else | 2300 | #else |
2311 | static inline unsigned long zone_spanned_pages_in_node(int nid, | 2301 | static inline unsigned long zone_spanned_pages_in_node(int nid, |
2312 | unsigned long zone_type, | 2302 | unsigned long zone_type, |
@@ -2325,10 +2315,6 @@ static inline unsigned long zone_absent_pages_in_node(int nid, | |||
2325 | return zholes_size[zone_type]; | 2315 | return zholes_size[zone_type]; |
2326 | } | 2316 | } |
2327 | 2317 | ||
2328 | static inline int memmap_zone_idx(struct page *lmem_map) | ||
2329 | { | ||
2330 | return MAX_NR_ZONES; | ||
2331 | } | ||
2332 | #endif | 2318 | #endif |
2333 | 2319 | ||
2334 | static void __init calculate_node_totalpages(struct pglist_data *pgdat, | 2320 | static void __init calculate_node_totalpages(struct pglist_data *pgdat, |
@@ -2421,7 +2407,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat, | |||
2421 | zone->zone_pgdat = pgdat; | 2407 | zone->zone_pgdat = pgdat; |
2422 | zone->free_pages = 0; | 2408 | zone->free_pages = 0; |
2423 | 2409 | ||
2424 | zone->temp_priority = zone->prev_priority = DEF_PRIORITY; | 2410 | zone->prev_priority = DEF_PRIORITY; |
2425 | 2411 | ||
2426 | zone_pcp_init(zone); | 2412 | zone_pcp_init(zone); |
2427 | INIT_LIST_HEAD(&zone->active_list); | 2413 | INIT_LIST_HEAD(&zone->active_list); |
@@ -3136,3 +3122,19 @@ unsigned long page_to_pfn(struct page *page) | |||
3136 | EXPORT_SYMBOL(pfn_to_page); | 3122 | EXPORT_SYMBOL(pfn_to_page); |
3137 | EXPORT_SYMBOL(page_to_pfn); | 3123 | EXPORT_SYMBOL(page_to_pfn); |
3138 | #endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ | 3124 | #endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ |
3125 | |||
3126 | #if MAX_NUMNODES > 1 | ||
3127 | /* | ||
3128 | * Find the highest possible node id. | ||
3129 | */ | ||
3130 | int highest_possible_node_id(void) | ||
3131 | { | ||
3132 | unsigned int node; | ||
3133 | unsigned int highest = 0; | ||
3134 | |||
3135 | for_each_node_mask(node, node_possible_map) | ||
3136 | highest = node; | ||
3137 | return highest; | ||
3138 | } | ||
3139 | EXPORT_SYMBOL(highest_possible_node_id); | ||
3140 | #endif | ||