Skip to content

Commit

Permalink
x86, memblock: Add memblock_x86_register_active_regions() and membloc…
Browse files Browse the repository at this point in the history
…k_x86_hole_size()

memblock_x86_register_active_regions() will be used to fill early_node_map,
the result will be memblock.memory.region AND numa data

memblock_x86_hole_size will be used to find hole size on memblock.memory.region
with specified range.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
  • Loading branch information
Yinghai Lu authored and H. Peter Anvin committed Aug 27, 2010
1 parent 4d5cf86 commit 88ba088
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
4 changes: 4 additions & 0 deletions arch/x86/include/asm/memblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ void memblock_x86_free_range(u64 start, u64 end);
struct range;
int get_free_all_memory_range(struct range **rangep, int nodeid);

void memblock_x86_register_active_regions(int nid, unsigned long start_pfn,
unsigned long last_pfn);
u64 memblock_x86_hole_size(u64 start, u64 end);

#endif
66 changes: 66 additions & 0 deletions arch/x86/mm/memblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,69 @@ void __init memblock_x86_free_range(u64 start, u64 end)

memblock_free(start, end - start);
}

/*
* Finds an active region in the address range from start_pfn to last_pfn and
* returns its range in ei_startpfn and ei_endpfn for the memblock entry.
*/
static int __init memblock_x86_find_active_region(const struct memblock_region *ei,
unsigned long start_pfn,
unsigned long last_pfn,
unsigned long *ei_startpfn,
unsigned long *ei_endpfn)
{
u64 align = PAGE_SIZE;

*ei_startpfn = round_up(ei->base, align) >> PAGE_SHIFT;
*ei_endpfn = round_down(ei->base + ei->size, align) >> PAGE_SHIFT;

/* Skip map entries smaller than a page */
if (*ei_startpfn >= *ei_endpfn)
return 0;

/* Skip if map is outside the node */
if (*ei_endpfn <= start_pfn || *ei_startpfn >= last_pfn)
return 0;

/* Check for overlaps */
if (*ei_startpfn < start_pfn)
*ei_startpfn = start_pfn;
if (*ei_endpfn > last_pfn)
*ei_endpfn = last_pfn;

return 1;
}

/* Walk the memblock.memory map and register active regions within a node */
void __init memblock_x86_register_active_regions(int nid, unsigned long start_pfn,
unsigned long last_pfn)
{
unsigned long ei_startpfn;
unsigned long ei_endpfn;
struct memblock_region *r;

for_each_memblock(memory, r)
if (memblock_x86_find_active_region(r, start_pfn, last_pfn,
&ei_startpfn, &ei_endpfn))
add_active_range(nid, ei_startpfn, ei_endpfn);
}

/*
* Find the hole size (in bytes) in the memory range.
* @start: starting address of the memory range to scan
* @end: ending address of the memory range to scan
*/
u64 __init memblock_x86_hole_size(u64 start, u64 end)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long last_pfn = end >> PAGE_SHIFT;
unsigned long ei_startpfn, ei_endpfn, ram = 0;
struct memblock_region *r;

for_each_memblock(memory, r)
if (memblock_x86_find_active_region(r, start_pfn, last_pfn,
&ei_startpfn, &ei_endpfn))
ram += ei_endpfn - ei_startpfn;

return end - start - ((u64)ram << PAGE_SHIFT);
}

0 comments on commit 88ba088

Please sign in to comment.