x86-64: Combine SRAT regions when possible

... i.e. when the hole between two regions isn't occupied by memory on
another node. This reduces the memory->node table size, thus reducing
cache footprint of lookups, which got increased significantly some
time ago, and things go back to how they were before that change on
the systems I looked at.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
LKML-Reference: <4BCF3230020000780003B3CA@vpn.id2.novell.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
Jan Beulich 2010-04-21 16:13:20 +01:00 committed by H. Peter Anvin
parent 1d16b0f2f3
commit 2e61878698

View File

@ -363,6 +363,54 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
for (i = 0; i < MAX_NUMNODES; i++)
cutoff_node(i, start, end);
/*
* Join together blocks on the same node, holes between
* which don't overlap with memory on other nodes.
*/
for (i = 0; i < num_node_memblks; ++i) {
int j, k;
for (j = i + 1; j < num_node_memblks; ++j) {
unsigned long start, end;
if (memblk_nodeid[i] != memblk_nodeid[j])
continue;
start = min(node_memblk_range[i].end,
node_memblk_range[j].end);
end = max(node_memblk_range[i].start,
node_memblk_range[j].start);
for (k = 0; k < num_node_memblks; ++k) {
if (memblk_nodeid[i] == memblk_nodeid[k])
continue;
if (start < node_memblk_range[k].end &&
end > node_memblk_range[k].start)
break;
}
if (k < num_node_memblks)
continue;
start = min(node_memblk_range[i].start,
node_memblk_range[j].start);
end = max(node_memblk_range[i].end,
node_memblk_range[j].end);
printk(KERN_INFO "SRAT: Node %d "
"[%Lx,%Lx) + [%Lx,%Lx) -> [%lx,%lx)\n",
memblk_nodeid[i],
node_memblk_range[i].start,
node_memblk_range[i].end,
node_memblk_range[j].start,
node_memblk_range[j].end,
start, end);
node_memblk_range[i].start = start;
node_memblk_range[i].end = end;
k = --num_node_memblks - j;
memmove(memblk_nodeid + j, memblk_nodeid + j+1,
k * sizeof(*memblk_nodeid));
memmove(node_memblk_range + j, node_memblk_range + j+1,
k * sizeof(*node_memblk_range));
--j;
}
}
memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks,
memblk_nodeid);
if (memnode_shift < 0) {