Skip to content

Commit

Permalink
x86, numa, 32-bit: use find_e820_area() to find KVA RAM on node
Browse files Browse the repository at this point in the history
don't assume we can use RAM near the end of every node.
Esp systems that have few memory and they could have
kva address and kva RAM all below max_low_pfn.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Yinghai Lu authored and Ingo Molnar committed Jun 10, 2008
1 parent cc1a9d8 commit 9043f00
Showing 1 changed file with 33 additions and 26 deletions.
59 changes: 33 additions & 26 deletions arch/x86/mm/discontig_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,17 +228,21 @@ static unsigned long calculate_numa_remap_pages(void)
{
int nid;
unsigned long size, reserve_pages = 0;
unsigned long pfn;

for_each_online_node(nid) {
unsigned old_end_pfn = node_end_pfn[nid];
u64 node_end_target;
u64 node_end_final;

/*
* The acpi/srat node info can show hot-add memroy zones
* where memory could be added but not currently present.
*/
printk("node %d pfn: [%lx - %lx]\n",
nid, node_start_pfn[nid], node_end_pfn[nid]);
if (node_start_pfn[nid] > max_pfn)
continue;
if (!node_end_pfn[nid])
continue;
if (node_end_pfn[nid] > max_pfn)
node_end_pfn[nid] = max_pfn;

Expand All @@ -250,37 +254,40 @@ static unsigned long calculate_numa_remap_pages(void)
/* now the roundup is correct, convert to PAGE_SIZE pages */
size = size * PTRS_PER_PTE;

/*
* Validate the region we are allocating only contains valid
* pages.
*/
for (pfn = node_end_pfn[nid] - size;
pfn < node_end_pfn[nid]; pfn++)
if (!page_is_ram(pfn))
break;

if (pfn != node_end_pfn[nid])
size = 0;
node_end_target = round_down(node_end_pfn[nid] - size,
PTRS_PER_PTE);
node_end_target <<= PAGE_SHIFT;
do {
node_end_final = find_e820_area(node_end_target,
((u64)node_end_pfn[nid])<<PAGE_SHIFT,
((u64)size)<<PAGE_SHIFT,
LARGE_PAGE_BYTES);
node_end_target -= LARGE_PAGE_BYTES;
} while (node_end_final == -1ULL &&
(node_end_target>>PAGE_SHIFT) > (node_start_pfn[nid]));

if (node_end_final == -1ULL)
panic("Can not get kva ram\n");

printk("Reserving %ld pages of KVA for lmem_map of node %d\n",
size, nid);
node_remap_size[nid] = size;
node_remap_offset[nid] = reserve_pages;
reserve_pages += size;
printk("Shrinking node %d from %ld pages to %ld pages\n",
nid, node_end_pfn[nid], node_end_pfn[nid] - size);

if (node_end_pfn[nid] & (PTRS_PER_PTE-1)) {
/*
* Align node_end_pfn[] and node_remap_start_pfn[] to
* pmd boundary. remap_numa_kva will barf otherwise.
*/
printk("Shrinking node %d further by %ld pages for proper alignment\n",
nid, node_end_pfn[nid] & (PTRS_PER_PTE-1));
size += node_end_pfn[nid] & (PTRS_PER_PTE-1);
}
printk("Shrinking node %d from %ld pages to %lld pages\n",
nid, node_end_pfn[nid], node_end_final>>PAGE_SHIFT);

/*
* prevent kva address below max_low_pfn want it on system
* with less memory later.
* layout will be: KVA address , KVA RAM
*/
if ((node_end_final>>PAGE_SHIFT) < max_low_pfn)
reserve_early(node_end_final,
node_end_final+(((u64)size)<<PAGE_SHIFT),
"KVA RAM");

node_end_pfn[nid] -= size;
node_end_pfn[nid] = node_end_final>>PAGE_SHIFT;
node_remap_start_pfn[nid] = node_end_pfn[nid];
shrink_active_range(nid, node_end_pfn[nid]);
}
Expand Down

0 comments on commit 9043f00

Please sign in to comment.