2 * Written by Kanoj Sarcar, SGI, Aug 1999
4 #include <linux/config.h>
5 #include <linux/kernel.h>
7 #include <linux/init.h>
8 #include <linux/bootmem.h>
9 #include <linux/mmzone.h>
10 #include <linux/spinlock.h>
12 int numnodes
= 1; /* Initialized for UMA platforms */
14 #ifndef CONFIG_DISCONTIGMEM
16 static bootmem_data_t contig_bootmem_data
;
17 pg_data_t contig_page_data
= { bdata
: &contig_bootmem_data
};
20 * This is meant to be invoked by platforms whose physical memory starts
21 * at a considerably higher value than 0. Examples are Super-H, ARM, m68k.
22 * Should be invoked with paramters (0, 0, unsigned long *[], start_paddr).
24 void __init
free_area_init_node(int nid
, pg_data_t
*pgdat
,
25 unsigned long *zones_size
, unsigned long zone_start_paddr
,
26 unsigned long *zholes_size
)
28 free_area_init_core(0, NODE_DATA(0), &mem_map
, zones_size
,
29 zone_start_paddr
, zholes_size
);
32 #endif /* !CONFIG_DISCONTIGMEM */
34 struct page
* alloc_pages_node(int nid
, int gfp_mask
, unsigned long order
)
36 return __alloc_pages(NODE_DATA(nid
)->node_zonelists
+ gfp_mask
, order
);
39 #ifdef CONFIG_DISCONTIGMEM
41 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
43 static spinlock_t node_lock
= SPIN_LOCK_UNLOCKED
;
45 void show_free_areas_node(int nid
)
49 spin_lock_irqsave(&node_lock
, flags
);
50 printk("Memory information for node %d:\n", nid
);
51 show_free_areas_core(nid
);
52 spin_unlock_irqrestore(&node_lock
, flags
);
56 * Nodes can be initialized parallely, in no particular order.
58 void __init
free_area_init_node(int nid
, pg_data_t
*pgdat
,
59 unsigned long *zones_size
, unsigned long zone_start_paddr
,
60 unsigned long *zholes_size
)
65 if (mem_map
== (mem_map_t
*)NULL
)
66 mem_map
= (mem_map_t
*)PAGE_OFFSET
;
68 free_area_init_core(nid
, pgdat
, &discard
, zones_size
, zone_start_paddr
,
73 * Get space for the valid bitmap.
75 for (i
= 0; i
< MAX_NR_ZONES
; i
++)
76 size
+= zones_size
[i
];
77 size
= LONG_ALIGN((size
+ 7) >> 3);
78 pgdat
->valid_addr_bitmap
= (unsigned long *)alloc_bootmem_node(nid
, size
);
79 memset(pgdat
->valid_addr_bitmap
, 0, size
);
83 * This can be refined. Currently, tries to do round robin, instead
84 * should do concentratic circle search, starting from current node.
86 struct page
* alloc_pages(int gfp_mask
, unsigned long order
)
91 static int nextnid
= 0;
93 if (order
>= MAX_ORDER
)
95 spin_lock_irqsave(&node_lock
, flags
);
98 if (nextnid
== numnodes
)
100 spin_unlock_irqrestore(&node_lock
, flags
);
102 while (tnode
< numnodes
) {
103 if ((ret
= alloc_pages_node(tnode
++, gfp_mask
, order
)))
107 while (tnode
!= startnode
) {
108 if ((ret
= alloc_pages_node(tnode
++, gfp_mask
, order
)))
114 #endif /* CONFIG_DISCONTIGMEM */