x86_64: fix cpu_to_node setup for sparse apic_ids
Subsystems (2)
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
@@ -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 */
Quoted 4 lines · Ravikiran G Thirumalai
While booting with SMT disabled in bios, when using acpi srat to setup cpu_to_node[], sparse
apic_idscreate 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 */
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_idscreate 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
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_idscreate 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
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)
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 < 0A kernel
BUG()is triggered by a call toset_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 forx86_64:
---------------------------------
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <linux/unistd.h>#define
__NR_set_mempolicy238
#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;
}Signed-off-by Eric Dumazet <[email protected]>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)