@@ -77,19 +77,75 @@ void __init zones_init(void)
7777 free_area_init_node (0 , zones_size , ARCH_PFN_OFFSET , NULL );
7878}
7979
80+ #ifdef CONFIG_HIGHMEM
81+ static void __init free_area_high (unsigned long pfn , unsigned long end )
82+ {
83+ for (; pfn < end ; pfn ++ )
84+ free_highmem_page (pfn_to_page (pfn ));
85+ }
86+
87+ static void __init free_highpages (void )
88+ {
89+ unsigned long max_low = max_low_pfn ;
90+ struct memblock_region * mem , * res ;
91+
92+ reset_all_zones_managed_pages ();
93+ /* set highmem page free */
94+ for_each_memblock (memory , mem ) {
95+ unsigned long start = memblock_region_memory_base_pfn (mem );
96+ unsigned long end = memblock_region_memory_end_pfn (mem );
97+
98+ /* Ignore complete lowmem entries */
99+ if (end <= max_low )
100+ continue ;
101+
102+ if (memblock_is_nomap (mem ))
103+ continue ;
104+
105+ /* Truncate partial highmem entries */
106+ if (start < max_low )
107+ start = max_low ;
108+
109+ /* Find and exclude any reserved regions */
110+ for_each_memblock (reserved , res ) {
111+ unsigned long res_start , res_end ;
112+
113+ res_start = memblock_region_reserved_base_pfn (res );
114+ res_end = memblock_region_reserved_end_pfn (res );
115+
116+ if (res_end < start )
117+ continue ;
118+ if (res_start < start )
119+ res_start = start ;
120+ if (res_start > end )
121+ res_start = end ;
122+ if (res_end > end )
123+ res_end = end ;
124+ if (res_start != start )
125+ free_area_high (start , res_start );
126+ start = res_end ;
127+ if (start == end )
128+ break ;
129+ }
130+
131+ /* And now free anything which remains */
132+ if (start < end )
133+ free_area_high (start , end );
134+ }
135+ }
136+ #else
137+ static void __init free_highpages (void )
138+ {
139+ }
140+ #endif
141+
80142/*
81143 * Initialize memory pages.
82144 */
83145
84146void __init mem_init (void )
85147{
86- #ifdef CONFIG_HIGHMEM
87- unsigned long tmp ;
88-
89- reset_all_zones_managed_pages ();
90- for (tmp = max_low_pfn ; tmp < max_pfn ; tmp ++ )
91- free_highmem_page (pfn_to_page (tmp ));
92- #endif
148+ free_highpages ();
93149
94150 max_mapnr = max_pfn - ARCH_PFN_OFFSET ;
95151 high_memory = (void * )__va (max_low_pfn << PAGE_SHIFT );
0 commit comments