VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / ia64 / mm / discontig.c
1 /*
2  * Copyright (c) 2000, 2003 Silicon Graphics, Inc.  All rights reserved.
3  * Copyright (c) 2001 Intel Corp.
4  * Copyright (c) 2001 Tony Luck <tony.luck@intel.com>
5  * Copyright (c) 2002 NEC Corp.
6  * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
7  */
8
9 /*
10  * Platform initialization for Discontig Memory
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/swap.h>
16 #include <linux/bootmem.h>
17 #include <linux/acpi.h>
18 #include <linux/efi.h>
19 #include <asm/pgalloc.h>
20 #include <asm/tlb.h>
21 #include <asm/meminit.h>
22 #include <asm/numa.h>
23 #include <asm/sections.h>
24
25 /*
26  * Track per-node information needed to setup the boot memory allocator, the
27  * per-node areas, and the real VM.
28  */
29 struct early_node_data {
30         struct ia64_node_data *node_data;
31         pg_data_t *pgdat;
32         unsigned long pernode_addr;
33         unsigned long pernode_size;
34         struct bootmem_data bootmem_data;
35         unsigned long num_physpages;
36         unsigned long num_dma_physpages;
37         unsigned long min_pfn;
38         unsigned long max_pfn;
39 };
40
41 static struct early_node_data mem_data[NR_NODES] __initdata;
42
43 /**
44  * reassign_cpu_only_nodes - called from find_memory to move CPU-only nodes to a memory node
45  *
46  * This function will move nodes with only CPUs (no memory)
47  * to a node with memory which is at the minimum numa_slit distance.
48  * Any reassigments will result in the compression of the nodes
49  * and renumbering the nid values where appropriate.
50  * The static declarations below are to avoid large stack size which
51  * makes the code not re-entrant.
52  */
53 static void __init reassign_cpu_only_nodes(void)
54 {
55         struct node_memblk_s *p;
56         int i, j, k, nnode, nid, cpu, cpunid;
57         u8 cslit, slit;
58         static DECLARE_BITMAP(nodes_with_mem, NR_NODES) __initdata;
59         static u8 numa_slit_fix[MAX_NUMNODES * MAX_NUMNODES] __initdata;
60         static int node_flip[NR_NODES] __initdata;
61
62         for (nnode = 0, p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
63                 if (!test_bit(p->nid, (void *) nodes_with_mem)) {
64                         set_bit(p->nid, (void *) nodes_with_mem);
65                         nnode++;
66                 }
67
68         /*
69          * All nids with memory.
70          */
71         if (nnode == numnodes)
72                 return;
73
74         /*
75          * Change nids and attempt to migrate CPU-only nodes
76          * to the best numa_slit (closest neighbor) possible.
77          * For reassigned CPU nodes a nid can't be arrived at
78          * until after this loop because the target nid's new
79          * identity might not have been established yet. So
80          * new nid values are fabricated above numnodes and
81          * mapped back later to their true value.
82          */
83         for (nid = 0, i = 0; i < numnodes; i++)  {
84                 if (test_bit(i, (void *) nodes_with_mem)) {
85                         /*
86                          * Save original nid value for numa_slit
87                          * fixup and node_cpuid reassignments.
88                          */
89                         node_flip[nid] = i;
90
91                         if (i == nid) {
92                                 nid++;
93                                 continue;
94                         }
95
96                         for (p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
97                                 if (p->nid == i)
98                                         p->nid = nid;
99
100                         cpunid = nid;
101                         nid++;
102                 } else
103                         cpunid = numnodes;
104
105                 for (cpu = 0; cpu < NR_CPUS; cpu++)
106                         if (node_cpuid[cpu].nid == i) {
107                                 /* For nodes not being reassigned just fix the cpu's nid. */
108                                 if (cpunid < numnodes) {
109                                         node_cpuid[cpu].nid = cpunid;
110                                         continue;
111                                 }
112
113                                 /*
114                                  * For nodes being reassigned, find best node by
115                                  * numa_slit information and then make a temporary
116                                  * nid value based on current nid and numnodes.
117                                  */
118                                 for (slit = 0xff, k = numnodes + numnodes, j = 0; j < numnodes; j++)
119                                         if (i == j)
120                                                 continue;
121                                         else if (test_bit(j, (void *) nodes_with_mem)) {
122                                                 cslit = numa_slit[i * numnodes + j];
123                                                 if (cslit < slit) {
124                                                         k = numnodes + j;
125                                                         slit = cslit;
126                                                 }
127                                         }
128
129                                 node_cpuid[cpu].nid = k;
130                         }
131         }
132
133         /*
134          * Fixup temporary nid values for CPU-only nodes.
135          */
136         for (cpu = 0; cpu < NR_CPUS; cpu++)
137                 if (node_cpuid[cpu].nid == (numnodes + numnodes))
138                         node_cpuid[cpu].nid = nnode - 1;
139                 else
140                         for (i = 0; i < nnode; i++)
141                                 if (node_flip[i] == (node_cpuid[cpu].nid - numnodes)) {
142                                         node_cpuid[cpu].nid = i;
143                                         break;
144                                 }
145
146         /*
147          * Fix numa_slit by compressing from larger
148          * nid array to reduced nid array.
149          */
150         for (i = 0; i < nnode; i++)
151                 for (j = 0; j < nnode; j++)
152                         numa_slit_fix[i * nnode + j] =
153                                 numa_slit[node_flip[i] * numnodes + node_flip[j]];
154
155         memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit));
156
157         for (i = nnode; i < numnodes; i++)
158                 node_set_offline(i);
159
160         numnodes = nnode;
161
162         return;
163 }
164
165 /*
166  * To prevent cache aliasing effects, align per-node structures so that they
167  * start at addresses that are strided by node number.
168  */
169 #define NODEDATA_ALIGN(addr, node)                                              \
170         ((((addr) + 1024*1024-1) & ~(1024*1024-1)) + (node)*PERCPU_PAGE_SIZE)
171
172 /**
173  * build_node_maps - callback to setup bootmem structs for each node
174  * @start: physical start of range
175  * @len: length of range
176  * @node: node where this range resides
177  *
178  * We allocate a struct bootmem_data for each piece of memory that we wish to
179  * treat as a virtually contiguous block (i.e. each node). Each such block
180  * must start on an %IA64_GRANULE_SIZE boundary, so we round the address down
181  * if necessary.  Any non-existent pages will simply be part of the virtual
182  * memmap.  We also update min_low_pfn and max_low_pfn here as we receive
183  * memory ranges from the caller.
184  */
185 static int __init build_node_maps(unsigned long start, unsigned long len,
186                                   int node)
187 {
188         unsigned long cstart, epfn, end = start + len;
189         struct bootmem_data *bdp = &mem_data[node].bootmem_data;
190
191         epfn = GRANULEROUNDUP(end) >> PAGE_SHIFT;
192         cstart = GRANULEROUNDDOWN(start);
193
194         if (!bdp->node_low_pfn) {
195                 bdp->node_boot_start = cstart;
196                 bdp->node_low_pfn = epfn;
197         } else {
198                 bdp->node_boot_start = min(cstart, bdp->node_boot_start);
199                 bdp->node_low_pfn = max(epfn, bdp->node_low_pfn);
200         }
201
202         min_low_pfn = min(min_low_pfn, bdp->node_boot_start>>PAGE_SHIFT);
203         max_low_pfn = max(max_low_pfn, bdp->node_low_pfn);
204
205         return 0;
206 }
207
208 /**
209  * early_nr_cpus_node - return number of cpus on a given node
210  * @node: node to check
211  *
212  * Count the number of cpus on @node.  We can't use nr_cpus_node() yet because
213  * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
214  * called yet.
215  */
216 static int early_nr_cpus_node(int node)
217 {
218         int cpu, n = 0;
219
220         for (cpu = 0; cpu < NR_CPUS; cpu++)
221                 if (node == node_cpuid[cpu].nid)
222                         n++;
223
224         return n;
225 }
226
227 /**
228  * find_pernode_space - allocate memory for memory map and per-node structures
229  * @start: physical start of range
230  * @len: length of range
231  * @node: node where this range resides
232  *
233  * This routine reserves space for the per-cpu data struct, the list of
234  * pg_data_ts and the per-node data struct.  Each node will have something like
235  * the following in the first chunk of addr. space large enough to hold it.
236  *
237  *    ________________________
238  *   |                        |
239  *   |~~~~~~~~~~~~~~~~~~~~~~~~| <-- NODEDATA_ALIGN(start, node) for the first
240  *   |    PERCPU_PAGE_SIZE *  |     start and length big enough
241  *   |        NR_CPUS         |
242  *   |------------------------|
243  *   |   local pg_data_t *    |
244  *   |------------------------|
245  *   |  local ia64_node_data  |
246  *   |------------------------|
247  *   |          ???           |
248  *   |________________________|
249  *
250  * Once this space has been set aside, the bootmem maps are initialized.  We
251  * could probably move the allocation of the per-cpu and ia64_node_data space
252  * outside of this function and use alloc_bootmem_node(), but doing it here
253  * is straightforward and we get the alignments we want so...
254  */
255 static int __init find_pernode_space(unsigned long start, unsigned long len,
256                                      int node)
257 {
258         unsigned long epfn, cpu, cpus;
259         unsigned long pernodesize = 0, pernode, pages, mapsize;
260         void *cpu_data;
261         struct bootmem_data *bdp = &mem_data[node].bootmem_data;
262
263         epfn = (start + len) >> PAGE_SHIFT;
264
265         pages = bdp->node_low_pfn - (bdp->node_boot_start >> PAGE_SHIFT);
266         mapsize = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
267
268         /*
269          * Make sure this memory falls within this node's usable memory
270          * since we may have thrown some away in build_maps().
271          */
272         if (start < bdp->node_boot_start || epfn > bdp->node_low_pfn)
273                 return 0;
274
275         /* Don't setup this node's local space twice... */
276         if (mem_data[node].pernode_addr)
277                 return 0;
278
279         /*
280          * Calculate total size needed, incl. what's necessary
281          * for good alignment and alias prevention.
282          */
283         cpus = early_nr_cpus_node(node);
284         pernodesize += PERCPU_PAGE_SIZE * cpus;
285         pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
286         pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
287         pernodesize = PAGE_ALIGN(pernodesize);
288         pernode = NODEDATA_ALIGN(start, node);
289
290         /* Is this range big enough for what we want to store here? */
291         if (start + len > (pernode + pernodesize + mapsize)) {
292                 mem_data[node].pernode_addr = pernode;
293                 mem_data[node].pernode_size = pernodesize;
294                 memset(__va(pernode), 0, pernodesize);
295
296                 cpu_data = (void *)pernode;
297                 pernode += PERCPU_PAGE_SIZE * cpus;
298
299                 mem_data[node].pgdat = __va(pernode);
300                 pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
301
302                 mem_data[node].node_data = __va(pernode);
303                 pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
304
305                 mem_data[node].pgdat->bdata = bdp;
306                 pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
307
308                 /*
309                  * Copy the static per-cpu data into the region we
310                  * just set aside and then setup __per_cpu_offset
311                  * for each CPU on this node.
312                  */
313                 for (cpu = 0; cpu < NR_CPUS; cpu++) {
314                         if (node == node_cpuid[cpu].nid) {
315                                 memcpy(__va(cpu_data), __phys_per_cpu_start,
316                                        __per_cpu_end - __per_cpu_start);
317                                 __per_cpu_offset[cpu] = (char*)__va(cpu_data) -
318                                         __per_cpu_start;
319                                 cpu_data += PERCPU_PAGE_SIZE;
320                         }
321                 }
322         }
323
324         return 0;
325 }
326
327 /**
328  * free_node_bootmem - free bootmem allocator memory for use
329  * @start: physical start of range
330  * @len: length of range
331  * @node: node where this range resides
332  *
333  * Simply calls the bootmem allocator to free the specified ranged from
334  * the given pg_data_t's bdata struct.  After this function has been called
335  * for all the entries in the EFI memory map, the bootmem allocator will
336  * be ready to service allocation requests.
337  */
338 static int __init free_node_bootmem(unsigned long start, unsigned long len,
339                                     int node)
340 {
341         free_bootmem_node(mem_data[node].pgdat, start, len);
342
343         return 0;
344 }
345
346 /**
347  * reserve_pernode_space - reserve memory for per-node space
348  *
349  * Reserve the space used by the bootmem maps & per-node space in the boot
350  * allocator so that when we actually create the real mem maps we don't
351  * use their memory.
352  */
353 static void __init reserve_pernode_space(void)
354 {
355         unsigned long base, size, pages;
356         struct bootmem_data *bdp;
357         int node;
358
359         for (node = 0; node < numnodes; node++) {
360                 pg_data_t *pdp = mem_data[node].pgdat;
361
362                 bdp = pdp->bdata;
363
364                 /* First the bootmem_map itself */
365                 pages = bdp->node_low_pfn - (bdp->node_boot_start>>PAGE_SHIFT);
366                 size = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
367                 base = __pa(bdp->node_bootmem_map);
368                 reserve_bootmem_node(pdp, base, size);
369
370                 /* Now the per-node space */
371                 size = mem_data[node].pernode_size;
372                 base = __pa(mem_data[node].pernode_addr);
373                 reserve_bootmem_node(pdp, base, size);
374         }
375 }
376
377 /**
378  * initialize_pernode_data - fixup per-cpu & per-node pointers
379  *
380  * Each node's per-node area has a copy of the global pg_data_t list, so
381  * we copy that to each node here, as well as setting the per-cpu pointer
382  * to the local node data structure.  The active_cpus field of the per-node
383  * structure gets setup by the platform_cpu_init() function later.
384  */
385 static void __init initialize_pernode_data(void)
386 {
387         int cpu, node;
388         pg_data_t *pgdat_list[NR_NODES];
389
390         for (node = 0; node < numnodes; node++)
391                 pgdat_list[node] = mem_data[node].pgdat;
392
393         /* Copy the pg_data_t list to each node and init the node field */
394         for (node = 0; node < numnodes; node++) {
395                 memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list,
396                        sizeof(pgdat_list));
397         }
398
399         /* Set the node_data pointer for each per-cpu struct */
400         for (cpu = 0; cpu < NR_CPUS; cpu++) {
401                 node = node_cpuid[cpu].nid;
402                 per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data;
403         }
404 }
405
406 /**
407  * find_memory - walk the EFI memory map and setup the bootmem allocator
408  *
409  * Called early in boot to setup the bootmem allocator, and to
410  * allocate the per-cpu and per-node structures.
411  */
412 void __init find_memory(void)
413 {
414         int node;
415
416         reserve_memory();
417
418         if (numnodes == 0) {
419                 printk(KERN_ERR "node info missing!\n");
420                 numnodes = 1;
421         }
422
423         min_low_pfn = -1;
424         max_low_pfn = 0;
425
426         if (numnodes > 1)
427                 reassign_cpu_only_nodes();
428
429         /* These actually end up getting called by call_pernode_memory() */
430         efi_memmap_walk(filter_rsvd_memory, build_node_maps);
431         efi_memmap_walk(filter_rsvd_memory, find_pernode_space);
432
433         /*
434          * Initialize the boot memory maps in reverse order since that's
435          * what the bootmem allocator expects
436          */
437         for (node = numnodes - 1; node >= 0; node--) {
438                 unsigned long pernode, pernodesize, map;
439                 struct bootmem_data *bdp;
440
441                 bdp = &mem_data[node].bootmem_data;
442                 pernode = mem_data[node].pernode_addr;
443                 pernodesize = mem_data[node].pernode_size;
444                 map = pernode + pernodesize;
445
446                 /* Sanity check... */
447                 if (!pernode)
448                         panic("pernode space for node %d "
449                               "could not be allocated!", node);
450
451                 init_bootmem_node(mem_data[node].pgdat,
452                                   map>>PAGE_SHIFT,
453                                   bdp->node_boot_start>>PAGE_SHIFT,
454                                   bdp->node_low_pfn);
455         }
456
457         efi_memmap_walk(filter_rsvd_memory, free_node_bootmem);
458
459         reserve_pernode_space();
460         initialize_pernode_data();
461
462         max_pfn = max_low_pfn;
463
464         find_initrd();
465 }
466
467 /**
468  * per_cpu_init - setup per-cpu variables
469  *
470  * find_pernode_space() does most of this already, we just need to set
471  * local_per_cpu_offset
472  */
473 void *per_cpu_init(void)
474 {
475         int cpu;
476
477         if (smp_processor_id() == 0) {
478                 for (cpu = 0; cpu < NR_CPUS; cpu++) {
479                         per_cpu(local_per_cpu_offset, cpu) =
480                                 __per_cpu_offset[cpu];
481                 }
482         }
483
484         return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
485 }
486
487 /**
488  * show_mem - give short summary of memory stats
489  *
490  * Shows a simple page count of reserved and used pages in the system.
491  * For discontig machines, it does this on a per-pgdat basis.
492  */
493 void show_mem(void)
494 {
495         int i, reserved = 0;
496         int shared = 0, cached = 0;
497         pg_data_t *pgdat;
498
499         printk("Mem-info:\n");
500         show_free_areas();
501         printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
502         for_each_pgdat(pgdat) {
503                 printk("Node ID: %d\n", pgdat->node_id);
504                 for(i = 0; i < pgdat->node_spanned_pages; i++) {
505                         if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
506                                 continue;
507                         if (PageReserved(pgdat->node_mem_map+i))
508                                 reserved++;
509                         else if (PageSwapCache(pgdat->node_mem_map+i))
510                                 cached++;
511                         else if (page_count(pgdat->node_mem_map+i))
512                                 shared += page_count(pgdat->node_mem_map+i)-1;
513                 }
514                 printk("\t%ld pages of RAM\n", pgdat->node_present_pages);
515                 printk("\t%d reserved pages\n", reserved);
516                 printk("\t%d pages shared\n", shared);
517                 printk("\t%d pages swap cached\n", cached);
518         }
519         printk("Total of %ld pages in page table cache\n", pgtable_cache_size);
520         printk("%d free buffer pages\n", nr_free_buffer_pages());
521 }
522
523 /**
524  * call_pernode_memory - use SRAT to call callback functions with node info
525  * @start: physical start of range
526  * @len: length of range
527  * @arg: function to call for each range
528  *
529  * efi_memmap_walk() knows nothing about layout of memory across nodes. Find
530  * out to which node a block of memory belongs.  Ignore memory that we cannot
531  * identify, and split blocks that run across multiple nodes.
532  *
533  * Take this opportunity to round the start address up and the end address
534  * down to page boundaries.
535  */
536 void call_pernode_memory(unsigned long start, unsigned long len, void *arg)
537 {
538         unsigned long rs, re, end = start + len;
539         void (*func)(unsigned long, unsigned long, int);
540         int i;
541
542         start = PAGE_ALIGN(start);
543         end &= PAGE_MASK;
544         if (start >= end)
545                 return;
546
547         func = arg;
548
549         if (!num_node_memblks) {
550                 /* No SRAT table, so assume one node (node 0) */
551                 if (start < end)
552                         (*func)(start, end - start, 0);
553                 return;
554         }
555
556         for (i = 0; i < num_node_memblks; i++) {
557                 rs = max(start, node_memblk[i].start_paddr);
558                 re = min(end, node_memblk[i].start_paddr +
559                          node_memblk[i].size);
560
561                 if (rs < re)
562                         (*func)(rs, re - rs, node_memblk[i].nid);
563
564                 if (re == end)
565                         break;
566         }
567 }
568
569 /**
570  * count_node_pages - callback to build per-node memory info structures
571  * @start: physical start of range
572  * @len: length of range
573  * @node: node where this range resides
574  *
575  * Each node has it's own number of physical pages, DMAable pages, start, and
576  * end page frame number.  This routine will be called by call_pernode_memory()
577  * for each piece of usable memory and will setup these values for each node.
578  * Very similar to build_maps().
579  */
580 static int count_node_pages(unsigned long start, unsigned long len, int node)
581 {
582         unsigned long end = start + len;
583
584         mem_data[node].num_physpages += len >> PAGE_SHIFT;
585         if (start <= __pa(MAX_DMA_ADDRESS))
586                 mem_data[node].num_dma_physpages +=
587                         (min(end, __pa(MAX_DMA_ADDRESS)) - start) >>PAGE_SHIFT;
588         start = GRANULEROUNDDOWN(start);
589         start = ORDERROUNDDOWN(start);
590         end = GRANULEROUNDUP(end);
591         mem_data[node].max_pfn = max(mem_data[node].max_pfn,
592                                      end >> PAGE_SHIFT);
593         mem_data[node].min_pfn = min(mem_data[node].min_pfn,
594                                      start >> PAGE_SHIFT);
595
596         return 0;
597 }
598
599 /**
600  * paging_init - setup page tables
601  *
602  * paging_init() sets up the page tables for each node of the system and frees
603  * the bootmem allocator memory for general use.
604  */
605 void paging_init(void)
606 {
607         unsigned long max_dma;
608         unsigned long zones_size[MAX_NR_ZONES];
609         unsigned long zholes_size[MAX_NR_ZONES];
610         unsigned long max_gap, pfn_offset = 0;
611         int node;
612
613         max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
614         max_gap = 0;
615         efi_memmap_walk(find_largest_hole, &max_gap);
616
617         /* so min() will work in count_node_pages */
618         for (node = 0; node < numnodes; node++)
619                 mem_data[node].min_pfn = ~0UL;
620
621         efi_memmap_walk(filter_rsvd_memory, count_node_pages);
622
623         for (node = 0; node < numnodes; node++) {
624                 memset(zones_size, 0, sizeof(zones_size));
625                 memset(zholes_size, 0, sizeof(zholes_size));
626
627                 num_physpages += mem_data[node].num_physpages;
628
629                 if (mem_data[node].min_pfn >= max_dma) {
630                         /* All of this node's memory is above ZONE_DMA */
631                         zones_size[ZONE_NORMAL] = mem_data[node].max_pfn -
632                                 mem_data[node].min_pfn;
633                         zholes_size[ZONE_NORMAL] = mem_data[node].max_pfn -
634                                 mem_data[node].min_pfn -
635                                 mem_data[node].num_physpages;
636                 } else if (mem_data[node].max_pfn < max_dma) {
637                         /* All of this node's memory is in ZONE_DMA */
638                         zones_size[ZONE_DMA] = mem_data[node].max_pfn -
639                                 mem_data[node].min_pfn;
640                         zholes_size[ZONE_DMA] = mem_data[node].max_pfn -
641                                 mem_data[node].min_pfn -
642                                 mem_data[node].num_dma_physpages;
643                 } else {
644                         /* This node has memory in both zones */
645                         zones_size[ZONE_DMA] = max_dma -
646                                 mem_data[node].min_pfn;
647                         zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] -
648                                 mem_data[node].num_dma_physpages;
649                         zones_size[ZONE_NORMAL] = mem_data[node].max_pfn -
650                                 max_dma;
651                         zholes_size[ZONE_NORMAL] = zones_size[ZONE_NORMAL] -
652                                 (mem_data[node].num_physpages -
653                                  mem_data[node].num_dma_physpages);
654                 }
655
656                 if (node == 0) {
657                         vmalloc_end -=
658                                 PAGE_ALIGN(max_low_pfn * sizeof(struct page));
659                         vmem_map = (struct page *) vmalloc_end;
660
661                         efi_memmap_walk(create_mem_map_page_table, 0);
662                         printk("Virtual mem_map starts at 0x%p\n", vmem_map);
663                 }
664
665                 pfn_offset = mem_data[node].min_pfn;
666
667                 free_area_init_node(node, NODE_DATA(node),
668                                     vmem_map + pfn_offset, zones_size,
669                                     pfn_offset, zholes_size);
670         }
671
672         zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
673 }