Skip to contentSkip to conversation

x86_64: fix cpu_to_node setup for sparse apic_ids

PATCH In review Ravikiran G Thirumalai 4 participants 6 messages Jul 28, 2005 – Aug 3, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86_64: fix cpu_to_node setup for sparse apic_ids

While booting with SMT disabled in bios, when using acpi srat to setup cpu_to_node[], sparse apic_ids create problems. Here's a fix for that.

arch/x86_64/mm/srat.c +11 -6
Index: linux-2.6.13-rc3/arch/x86_64/mm/srat.c
===================================================================
@@ -20,6 +20,9 @@
 
 static struct acpi_table_slit *acpi_slit;
 
+/* Internal processor count */
+static unsigned int __initdata num_processors = 0;
+
 static nodemask_t nodes_parsed __initdata;
 static nodemask_t nodes_found __initdata;
 static struct node nodes[MAX_NUMNODES] __initdata;
@@ -101,16 +104,18 @@
 		bad_srat();
 		return;
 	}
-	if (pa->apic_id >= NR_CPUS) {
-		printk(KERN_ERR "SRAT: lapic %u too large.\n",
-		       pa->apic_id);
+	if (num_processors >= NR_CPUS) {
+		printk(KERN_ERR "SRAT: Processor #%d (lapic %u) INVALID. (Max ID: %d).\n",
+			num_processors, pa->apic_id, NR_CPUS);
 		bad_srat();
 		return;
 	}
-	cpu_to_node[pa->apic_id] = node;
+	cpu_to_node[num_processors] = node;
 	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
-	       pxm, pa->apic_id, node);
+	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> CPU %u -> Node %u\n",
+	       pxm, pa->apic_id, num_processors, node);
+
+	num_processors++;
 }
 
 /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
#1 lore raw
Quoted 4 lines · Ravikiran G Thirumalai

While booting with SMT disabled in bios, when using acpi srat to setup cpu_to_node[], sparse apic_ids create problems. Here's a fix for that.

Again, I don't have enough info here to judge the urgency of this patch.

What are the consequences and risks of not having this patch in 2.6.13, and to how many machines?

Quoted 40 lines

Index: linux-2.6.13-rc3/arch/x86_64/mm/srat.c
===================================================================

arch/x86_64/mm/srat.c +11 -6
@@ -20,6 +20,9 @@
 
 static struct acpi_table_slit *acpi_slit;
 
+/* Internal processor count */
+static unsigned int __initdata num_processors = 0;
+
 static nodemask_t nodes_parsed __initdata;
 static nodemask_t nodes_found __initdata;
 static struct node nodes[MAX_NUMNODES] __initdata;
@@ -101,16 +104,18 @@
 		bad_srat();
 		return;
 	}
-	if (pa->apic_id >= NR_CPUS) {
-		printk(KERN_ERR "SRAT: lapic %u too large.\n",
-		       pa->apic_id);
+	if (num_processors >= NR_CPUS) {
+		printk(KERN_ERR "SRAT: Processor #%d (lapic %u) INVALID. (Max ID: %d).\n",
+			num_processors, pa->apic_id, NR_CPUS);
 		bad_srat();
 		return;
 	}
-	cpu_to_node[pa->apic_id] = node;
+	cpu_to_node[num_processors] = node;
 	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
-	       pxm, pa->apic_id, node);
+	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> CPU %u -> Node %u\n",
+	       pxm, pa->apic_id, num_processors, node);
+
+	num_processors++;
 }
 
 /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
#2 lore raw
Quoted 11 lines · Andrew Morton
Quoted 4 lines · Ravikiran G Thirumalai

While booting with SMT disabled in bios, when using acpi srat to setup cpu_to_node[], sparse apic_ids create problems. Here's a fix for that.

Again, I don't have enough info here to judge the urgency of this patch.

What are the consequences and risks of not having this patch in 2.6.13, and to how many machines?

Without this patch, intel x86_64 boxes with hyperthreading disabled in the bios (and which rely on srat for numa setup) endup having incorrect values in cpu_to_node[] arrays, causing sched domains to be built incorrectly etc.

Thanks,
Kiran

#3 lore raw
In reply to Andrew Morton
Quoted 7 lines · Andrew Morton
Quoted 4 lines · Ravikiran G Thirumalai

While booting with SMT disabled in bios, when using acpi srat to setup cpu_to_node[], sparse apic_ids create problems. Here's a fix for that.

Again, I don't have enough info here to judge the urgency of this patch.

The patch is broken, don't apply please.

Ravi, there is no reason the order of CPUs in SRAT has anything to do with the order CPUs are brought up.

-Andi

#4 lore raw

PATCH 1/1 MM, NUMA : sys_set_mempolicy() doesnt check if mode < 0

MM, NUMA : sys_set_mempolicy() doesnt check if mode < 0

A kernel BUG() is triggered by a call to set_mempolicy() with a negative first argument. This is because the mode is declared as an int, and the validity check doesnt check < 0 values. Alternatively, mode could be declared as unsigned int or unsigned long.

Thank you
Eric
---------------------------------
Test program for x86_64:
---------------------------------
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/unistd.h>

#define __NR_set_mempolicy 238
#define __sys_set_mempolicy(mode, nmask, maxnode) _syscall3(int, set_mempolicy, int, mode, unsigned long *, nmask, unsigned long, maxnode) static __sys_set_mempolicy(mode, nmask, maxnode)

unsigned long nodes = 3;

int main()
{
int ret = set_mempolicy(-6, &nodes, 2);
printf("result=%d errno=%d\n", ret, errno);
return 0;
}

mm/mempolicy.c +1 -1
@@ -443,7 +443,7 @@
 	struct mempolicy *new;
 	DECLARE_BITMAP(nodes, MAX_NUMNODES);
 
-	if (mode > MPOL_MAX)
+	if ((unsigned int)mode > MPOL_MAX)
 		return -EINVAL;
 	err = get_nodes(nodes, nmask, maxnode, mode);
 	if (err)
#5 lore raw

Re: [PATCH] MM, NUMA : sys_set_mempolicy() doesnt check if mode < 0

Quoted 7 lines · Eric Dumazet

MM, NUMA : sys_set_mempolicy() doesnt check if mode < 0

A kernel BUG() is triggered by a call to set_mempolicy() with a negative first argument.
This is because the mode is declared as an int, and the validity check doesnt check < 0 values.
Alternatively, mode could be declared as unsigned int or unsigned long.

Thanks looks good. Andrew, can you apply that one?

-Andi

Quoted 40 lines

Thank you
Eric
---------------------------------
Test program for x86_64:
---------------------------------
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/unistd.h>

#define __NR_set_mempolicy 238
#define __sys_set_mempolicy(mode, nmask, maxnode) _syscall3(int, set_mempolicy, int, mode, unsigned long *, nmask, unsigned long, maxnode) static __sys_set_mempolicy(mode, nmask, maxnode)

unsigned long nodes = 3;

int main()
{
int ret = set_mempolicy(-6, &nodes, 2);
printf("result=%d errno=%d\n", ret, errno);
return 0;
}

mm/mempolicy.c +1 -1
@@ -443,7 +443,7 @@
 	struct mempolicy *new;
 	DECLARE_BITMAP(nodes, MAX_NUMNODES);
 
-	if (mode > MPOL_MAX)
+	if ((unsigned int)mode > MPOL_MAX)
 		return -EINVAL;
 	err = get_nodes(nodes, nmask, maxnode, mode);
 	if (err)