Commit 8f13ed2f authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: Fix ACPI SRAT NUMA parsing

Fix fallout from the recent nodemask_t changes. The node ids assigned
in the SRAT parser were off by one.

I added a new first_unset_node() function to nodemask.h to allocate
IDs sanely.
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 04a2b7d0
...@@ -20,17 +20,20 @@ ...@@ -20,17 +20,20 @@
static struct acpi_table_slit *acpi_slit; static struct acpi_table_slit *acpi_slit;
static DECLARE_BITMAP(nodes_parsed, MAX_NUMNODES) __initdata; static nodemask_t nodes_parsed __initdata;
static nodemask_t nodes_found __initdata;
static struct node nodes[MAX_NUMNODES] __initdata; static struct node nodes[MAX_NUMNODES] __initdata;
static __u8 pxm2node[256] __initdata = { [0 ... 255] = 0xff }; static __u8 pxm2node[256] __initdata = { [0 ... 255] = 0xff };
static __init int setup_node(int pxm) static __init int setup_node(int pxm)
{ {
if (pxm2node[pxm] == 0xff) { unsigned node = pxm2node[pxm];
if (num_online_nodes() >= MAX_NUMNODES) if (node == 0xff) {
if (nodes_weight(nodes_found) >= MAX_NUMNODES)
return -1; return -1;
pxm2node[pxm] = num_online_nodes(); node = first_unset_node(nodes_found);
node_set_online(num_online_nodes()); node_set(node, nodes_found);
pxm2node[pxm] = node;
} }
return pxm2node[pxm]; return pxm2node[pxm];
} }
...@@ -140,7 +143,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) ...@@ -140,7 +143,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
return; return;
} }
nd = &nodes[node]; nd = &nodes[node];
if (!test_and_set_bit(node, &nodes_parsed)) { if (!node_test_and_set(node, nodes_parsed)) {
nd->start = start; nd->start = start;
nd->end = end; nd->end = end;
} else { } else {
...@@ -171,7 +174,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) ...@@ -171,7 +174,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
return -1; return -1;
} }
for (i = 0; i < MAX_NUMNODES; i++) { for (i = 0; i < MAX_NUMNODES; i++) {
if (!test_bit(i, &nodes_parsed)) if (!node_isset(i, nodes_parsed))
continue; continue;
cutoff_node(i, start, end); cutoff_node(i, start, end);
if (nodes[i].start == nodes[i].end) if (nodes[i].start == nodes[i].end)
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
* *
* int first_node(mask) Number lowest set bit, or MAX_NUMNODES * int first_node(mask) Number lowest set bit, or MAX_NUMNODES
* int next_node(node, mask) Next node past 'node', or MAX_NUMNODES * int next_node(node, mask) Next node past 'node', or MAX_NUMNODES
* int first_unset_node(mask) First node not set in mask, or
* MAX_NUMNODES.
* *
* nodemask_t nodemask_of_node(node) Return nodemask with bit 'node' set * nodemask_t nodemask_of_node(node) Return nodemask with bit 'node' set
* NODE_MASK_ALL Initializer - all bits set * NODE_MASK_ALL Initializer - all bits set
...@@ -235,6 +237,13 @@ static inline int __next_node(int n, const nodemask_t *srcp, int nbits) ...@@ -235,6 +237,13 @@ static inline int __next_node(int n, const nodemask_t *srcp, int nbits)
m; \ m; \
}) })
#define first_unset_node(mask) __first_unset_node(&(mask))
static inline int __first_unset_node(const nodemask_t *maskp)
{
return min_t(int,MAX_NUMNODES,
find_first_zero_bit(maskp->bits, MAX_NUMNODES));
}
#define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES) #define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES)
#if MAX_NUMNODES <= BITS_PER_LONG #if MAX_NUMNODES <= BITS_PER_LONG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment