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.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 20e239599db0..5c1b8982a6da 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(nr_swap_pages);
68 * Used by page_zone() to look up the address of the struct zone whose 68 * Used by page_zone() to look up the address of the struct zone whose
69 * id is encoded in the upper bits of page->flags 69 * id is encoded in the upper bits of page->flags
70 */ 70 */
71struct zone *zone_table[1 << (ZONES_SHIFT + NODES_SHIFT)]; 71struct zone *zone_table[1 << ZONETABLE_SHIFT];
72EXPORT_SYMBOL(zone_table); 72EXPORT_SYMBOL(zone_table);
73 73
74static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; 74static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
@@ -1649,11 +1649,15 @@ static void __init calculate_zone_totalpages(struct pglist_data *pgdat,
1649void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone, 1649void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
1650 unsigned long start_pfn) 1650 unsigned long start_pfn)
1651{ 1651{
1652 struct page *start = pfn_to_page(start_pfn);
1653 struct page *page; 1652 struct page *page;
1653 int end_pfn = start_pfn + size;
1654 int pfn;
1654 1655
1655 for (page = start; page < (start + size); page++) { 1656 for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) {
1656 set_page_links(page, zone, nid); 1657 if (!early_pfn_valid(pfn))
1658 continue;
1659 page = pfn_to_page(pfn);
1660 set_page_links(page, zone, nid, pfn);
1657 set_page_count(page, 0); 1661 set_page_count(page, 0);
1658 reset_page_mapcount(page); 1662 reset_page_mapcount(page);
1659 SetPageReserved(page); 1663 SetPageReserved(page);
@@ -1677,6 +1681,20 @@ void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone,
1677 } 1681 }
1678} 1682}
1679 1683
1684#define ZONETABLE_INDEX(x, zone_nr) ((x << ZONES_SHIFT) | zone_nr)
1685void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
1686 unsigned long size)
1687{
1688 unsigned long snum = pfn_to_section_nr(pfn);
1689 unsigned long end = pfn_to_section_nr(pfn + size);
1690
1691 if (FLAGS_HAS_NODE)
1692 zone_table[ZONETABLE_INDEX(nid, zid)] = zone;
1693 else
1694 for (; snum <= end; snum++)
1695 zone_table[ZONETABLE_INDEX(snum, zid)] = zone;
1696}
1697
1680#ifndef __HAVE_ARCH_MEMMAP_INIT 1698#ifndef __HAVE_ARCH_MEMMAP_INIT
1681#define memmap_init(size, nid, zone, start_pfn) \ 1699#define memmap_init(size, nid, zone, start_pfn) \
1682 memmap_init_zone((size), (nid), (zone), (start_pfn)) 1700 memmap_init_zone((size), (nid), (zone), (start_pfn))
@@ -1861,7 +1879,6 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1861 unsigned long size, realsize; 1879 unsigned long size, realsize;
1862 unsigned long batch; 1880 unsigned long batch;
1863 1881
1864 zone_table[NODEZONE(nid, j)] = zone;
1865 realsize = size = zones_size[j]; 1882 realsize = size = zones_size[j];
1866 if (zholes_size) 1883 if (zholes_size)
1867 realsize -= zholes_size[j]; 1884 realsize -= zholes_size[j];
@@ -1927,6 +1944,8 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1927 1944
1928 memmap_init(size, nid, j, zone_start_pfn); 1945 memmap_init(size, nid, j, zone_start_pfn);
1929 1946
1947 zonetable_add(zone, nid, j, zone_start_pfn, size);
1948
1930 zone_start_pfn += size; 1949 zone_start_pfn += size;
1931 1950
1932 zone_init_free_lists(pgdat, zone, zone->spanned_pages); 1951 zone_init_free_lists(pgdat, zone, zone->spanned_pages);
@@ -1935,28 +1954,30 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1935 1954
1936static void __init alloc_node_mem_map(struct pglist_data *pgdat) 1955static void __init alloc_node_mem_map(struct pglist_data *pgdat)
1937{ 1956{
1938 unsigned long size;
1939 struct page *map;
1940
1941 /* Skip empty nodes */ 1957 /* Skip empty nodes */
1942 if (!pgdat->node_spanned_pages) 1958 if (!pgdat->node_spanned_pages)
1943 return; 1959 return;
1944 1960
1961#ifdef CONFIG_FLAT_NODE_MEM_MAP
1945 /* ia64 gets its own node_mem_map, before this, without bootmem */ 1962 /* ia64 gets its own node_mem_map, before this, without bootmem */
1946 if (!pgdat->node_mem_map) { 1963 if (!pgdat->node_mem_map) {
1964 unsigned long size;
1965 struct page *map;
1966
1947 size = (pgdat->node_spanned_pages + 1) * sizeof(struct page); 1967 size = (pgdat->node_spanned_pages + 1) * sizeof(struct page);
1948 map = alloc_remap(pgdat->node_id, size); 1968 map = alloc_remap(pgdat->node_id, size);
1949 if (!map) 1969 if (!map)
1950 map = alloc_bootmem_node(pgdat, size); 1970 map = alloc_bootmem_node(pgdat, size);
1951 pgdat->node_mem_map = map; 1971 pgdat->node_mem_map = map;
1952 } 1972 }
1953#ifndef CONFIG_DISCONTIGMEM 1973#ifdef CONFIG_FLATMEM
1954 /* 1974 /*
1955 * With no DISCONTIG, the global mem_map is just set as node 0's 1975 * With no DISCONTIG, the global mem_map is just set as node 0's
1956 */ 1976 */
1957 if (pgdat == NODE_DATA(0)) 1977 if (pgdat == NODE_DATA(0))
1958 mem_map = NODE_DATA(0)->node_mem_map; 1978 mem_map = NODE_DATA(0)->node_mem_map;
1959#endif 1979#endif
1980#endif /* CONFIG_FLAT_NODE_MEM_MAP */
1960} 1981}
1961 1982
1962void __init free_area_init_node(int nid, struct pglist_data *pgdat, 1983void __init free_area_init_node(int nid, struct pglist_data *pgdat,