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 | ||
