@@ -176,11 +176,22 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low,
176176int pfn_valid (unsigned long pfn )
177177{
178178 phys_addr_t addr = __pfn_to_phys (pfn );
179+ unsigned long pageblock_size = PAGE_SIZE * pageblock_nr_pages ;
179180
180181 if (__phys_to_pfn (addr ) != pfn )
181182 return 0 ;
182183
183- return memblock_is_map_memory (__pfn_to_phys (pfn ));
184+ /*
185+ * If address less than pageblock_size bytes away from a present
186+ * memory chunk there still will be a memory map entry for it
187+ * because we round freed memory map to the pageblock boundaries.
188+ */
189+ if (memblock_overlaps_region (& memblock .memory ,
190+ ALIGN_DOWN (addr , pageblock_size ),
191+ pageblock_size ))
192+ return 1 ;
193+
194+ return 0 ;
184195}
185196EXPORT_SYMBOL (pfn_valid );
186197#endif
@@ -371,14 +382,14 @@ static void __init free_unused_memmap(void)
371382 */
372383 start = min (start ,
373384 ALIGN (prev_end , PAGES_PER_SECTION ));
374- #else
385+ #endif
375386 /*
376- * Align down here since the VM subsystem insists that the
377- * memmap entries are valid from the bank start aligned to
378- * MAX_ORDER_NR_PAGES.
387+ * Align down here since many operations in VM subsystem
388+ * presume that there are no holes in the memory map inside
389+ * a pageblock
379390 */
380- start = round_down (start , MAX_ORDER_NR_PAGES );
381- #endif
391+ start = round_down (start , pageblock_nr_pages );
392+
382393 /*
383394 * If we had a previous bank, and there is a space
384395 * between the current bank and the previous, free it.
@@ -387,18 +398,20 @@ static void __init free_unused_memmap(void)
387398 free_memmap (prev_end , start );
388399
389400 /*
390- * Align up here since the VM subsystem insists that the
391- * memmap entries are valid from the bank end aligned to
392- * MAX_ORDER_NR_PAGES.
401+ * Align up here since many operations in VM subsystem
402+ * presume that there are no holes in the memory map inside
403+ * a pageblock
393404 */
394405 prev_end = ALIGN (memblock_region_memory_end_pfn (reg ),
395- MAX_ORDER_NR_PAGES );
406+ pageblock_nr_pages );
396407 }
397408
398409#ifdef CONFIG_SPARSEMEM
399- if (!IS_ALIGNED (prev_end , PAGES_PER_SECTION ))
410+ if (!IS_ALIGNED (prev_end , PAGES_PER_SECTION )) {
411+ prev_end = ALIGN (prev_end , pageblock_nr_pages );
400412 free_memmap (prev_end ,
401413 ALIGN (prev_end , PAGES_PER_SECTION ));
414+ }
402415#endif
403416}
404417
0 commit comments