aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c95
1 files changed, 76 insertions, 19 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 53242344a774..79ac4afc908c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2328,7 +2328,6 @@ static void build_zonelists(pg_data_t *pgdat)
2328static void build_zonelist_cache(pg_data_t *pgdat) 2328static void build_zonelist_cache(pg_data_t *pgdat)
2329{ 2329{
2330 pgdat->node_zonelists[0].zlcache_ptr = NULL; 2330 pgdat->node_zonelists[0].zlcache_ptr = NULL;
2331 pgdat->node_zonelists[1].zlcache_ptr = NULL;
2332} 2331}
2333 2332
2334#endif /* CONFIG_NUMA */ 2333#endif /* CONFIG_NUMA */
@@ -2930,6 +2929,18 @@ void __init free_bootmem_with_active_regions(int nid,
2930 } 2929 }
2931} 2930}
2932 2931
2932void __init work_with_active_regions(int nid, work_fn_t work_fn, void *data)
2933{
2934 int i;
2935 int ret;
2936
2937 for_each_active_range_index_in_nid(i, nid) {
2938 ret = work_fn(early_node_map[i].start_pfn,
2939 early_node_map[i].end_pfn, data);
2940 if (ret)
2941 break;
2942 }
2943}
2933/** 2944/**
2934 * sparse_memory_present_with_active_regions - Call memory_present for each active range 2945 * sparse_memory_present_with_active_regions - Call memory_present for each active range
2935 * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used. 2946 * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used.
@@ -3462,6 +3473,11 @@ void __paginginit free_area_init_node(int nid, struct pglist_data *pgdat,
3462 calculate_node_totalpages(pgdat, zones_size, zholes_size); 3473 calculate_node_totalpages(pgdat, zones_size, zholes_size);
3463 3474
3464 alloc_node_mem_map(pgdat); 3475 alloc_node_mem_map(pgdat);
3476#ifdef CONFIG_FLAT_NODE_MEM_MAP
3477 printk(KERN_DEBUG "free_area_init_node: node %d, pgdat %08lx, node_mem_map %08lx\n",
3478 nid, (unsigned long)pgdat,
3479 (unsigned long)pgdat->node_mem_map);
3480#endif
3465 3481
3466 free_area_init_core(pgdat, zones_size, zholes_size); 3482 free_area_init_core(pgdat, zones_size, zholes_size);
3467} 3483}
@@ -3504,7 +3520,7 @@ void __init add_active_range(unsigned int nid, unsigned long start_pfn,
3504{ 3520{
3505 int i; 3521 int i;
3506 3522
3507 printk(KERN_DEBUG "Entering add_active_range(%d, %lu, %lu) " 3523 printk(KERN_DEBUG "Entering add_active_range(%d, %#lx, %#lx) "
3508 "%d entries of %d used\n", 3524 "%d entries of %d used\n",
3509 nid, start_pfn, end_pfn, 3525 nid, start_pfn, end_pfn,
3510 nr_nodemap_entries, MAX_ACTIVE_REGIONS); 3526 nr_nodemap_entries, MAX_ACTIVE_REGIONS);
@@ -3548,27 +3564,68 @@ void __init add_active_range(unsigned int nid, unsigned long start_pfn,
3548} 3564}
3549 3565
3550/** 3566/**
3551 * shrink_active_range - Shrink an existing registered range of PFNs 3567 * remove_active_range - Shrink an existing registered range of PFNs
3552 * @nid: The node id the range is on that should be shrunk 3568 * @nid: The node id the range is on that should be shrunk
3553 * @old_end_pfn: The old end PFN of the range 3569 * @start_pfn: The new PFN of the range
3554 * @new_end_pfn: The new PFN of the range 3570 * @end_pfn: The new PFN of the range
3555 * 3571 *
3556 * i386 with NUMA use alloc_remap() to store a node_mem_map on a local node. 3572 * i386 with NUMA use alloc_remap() to store a node_mem_map on a local node.
3557 * The map is kept at the end physical page range that has already been 3573 * The map is kept near the end physical page range that has already been
3558 * registered with add_active_range(). This function allows an arch to shrink 3574 * registered. This function allows an arch to shrink an existing registered
3559 * an existing registered range. 3575 * range.
3560 */ 3576 */
3561void __init shrink_active_range(unsigned int nid, unsigned long old_end_pfn, 3577void __init remove_active_range(unsigned int nid, unsigned long start_pfn,
3562 unsigned long new_end_pfn) 3578 unsigned long end_pfn)
3563{ 3579{
3564 int i; 3580 int i, j;
3581 int removed = 0;
3582
3583 printk(KERN_DEBUG "remove_active_range (%d, %lu, %lu)\n",
3584 nid, start_pfn, end_pfn);
3565 3585
3566 /* Find the old active region end and shrink */ 3586 /* Find the old active region end and shrink */
3567 for_each_active_range_index_in_nid(i, nid) 3587 for_each_active_range_index_in_nid(i, nid) {
3568 if (early_node_map[i].end_pfn == old_end_pfn) { 3588 if (early_node_map[i].start_pfn >= start_pfn &&
3569 early_node_map[i].end_pfn = new_end_pfn; 3589 early_node_map[i].end_pfn <= end_pfn) {
3570 break; 3590 /* clear it */
3591 early_node_map[i].start_pfn = 0;
3592 early_node_map[i].end_pfn = 0;
3593 removed = 1;
3594 continue;
3595 }
3596 if (early_node_map[i].start_pfn < start_pfn &&
3597 early_node_map[i].end_pfn > start_pfn) {
3598 unsigned long temp_end_pfn = early_node_map[i].end_pfn;
3599 early_node_map[i].end_pfn = start_pfn;
3600 if (temp_end_pfn > end_pfn)
3601 add_active_range(nid, end_pfn, temp_end_pfn);
3602 continue;
3571 } 3603 }
3604 if (early_node_map[i].start_pfn >= start_pfn &&
3605 early_node_map[i].end_pfn > end_pfn &&
3606 early_node_map[i].start_pfn < end_pfn) {
3607 early_node_map[i].start_pfn = end_pfn;
3608 continue;
3609 }
3610 }
3611
3612 if (!removed)
3613 return;
3614
3615 /* remove the blank ones */
3616 for (i = nr_nodemap_entries - 1; i > 0; i--) {
3617 if (early_node_map[i].nid != nid)
3618 continue;
3619 if (early_node_map[i].end_pfn)
3620 continue;
3621 /* we found it, get rid of it */
3622 for (j = i; j < nr_nodemap_entries - 1; j++)
3623 memcpy(&early_node_map[j], &early_node_map[j+1],
3624 sizeof(early_node_map[j]));
3625 j = nr_nodemap_entries - 1;
3626 memset(&early_node_map[j], 0, sizeof(early_node_map[j]));
3627 nr_nodemap_entries--;
3628 }
3572} 3629}
3573 3630
3574/** 3631/**
@@ -3612,7 +3669,7 @@ static void __init sort_node_map(void)
3612} 3669}
3613 3670
3614/* Find the lowest pfn for a node */ 3671/* Find the lowest pfn for a node */
3615unsigned long __init find_min_pfn_for_node(unsigned long nid) 3672unsigned long __init find_min_pfn_for_node(int nid)
3616{ 3673{
3617 int i; 3674 int i;
3618 unsigned long min_pfn = ULONG_MAX; 3675 unsigned long min_pfn = ULONG_MAX;
@@ -3623,7 +3680,7 @@ unsigned long __init find_min_pfn_for_node(unsigned long nid)
3623 3680
3624 if (min_pfn == ULONG_MAX) { 3681 if (min_pfn == ULONG_MAX) {
3625 printk(KERN_WARNING 3682 printk(KERN_WARNING
3626 "Could not find start_pfn for node %lu\n", nid); 3683 "Could not find start_pfn for node %d\n", nid);
3627 return 0; 3684 return 0;
3628 } 3685 }
3629 3686
@@ -3879,7 +3936,7 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
3879 for (i = 0; i < MAX_NR_ZONES; i++) { 3936 for (i = 0; i < MAX_NR_ZONES; i++) {
3880 if (i == ZONE_MOVABLE) 3937 if (i == ZONE_MOVABLE)
3881 continue; 3938 continue;
3882 printk(" %-8s %8lu -> %8lu\n", 3939 printk(" %-8s %0#10lx -> %0#10lx\n",
3883 zone_names[i], 3940 zone_names[i],
3884 arch_zone_lowest_possible_pfn[i], 3941 arch_zone_lowest_possible_pfn[i],
3885 arch_zone_highest_possible_pfn[i]); 3942 arch_zone_highest_possible_pfn[i]);
@@ -3895,7 +3952,7 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
3895 /* Print out the early_node_map[] */ 3952 /* Print out the early_node_map[] */
3896 printk("early_node_map[%d] active PFN ranges\n", nr_nodemap_entries); 3953 printk("early_node_map[%d] active PFN ranges\n", nr_nodemap_entries);
3897 for (i = 0; i < nr_nodemap_entries; i++) 3954 for (i = 0; i < nr_nodemap_entries; i++)
3898 printk(" %3d: %8lu -> %8lu\n", early_node_map[i].nid, 3955 printk(" %3d: %0#10lx -> %0#10lx\n", early_node_map[i].nid,
3899 early_node_map[i].start_pfn, 3956 early_node_map[i].start_pfn,
3900 early_node_map[i].end_pfn); 3957 early_node_map[i].end_pfn);
3901 3958