Skip to contentSkip to conversation

x86_64: Support for new UV apic

PATCH In review Jack Steiner 3 participants 19 messages Mar 28, 2008 – Mar 31, 2008

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

PATCH 8/8 x86_64: Support for new UV apic

UV supports really big systems. So big, in fact, that the APICID register does not contain enough bits to contain an APICID that is unique across all cpus.

The UV BIOS supports 3 APICID modes:

- legacy mode. This mode uses the old APIC mode where APICID is in bits [31:24] of the APICID register.

- x2apic mode. This mode is whitebox-compatible. APICIDs are unique across all cpus. Standard x2apic APIC operations (Intel-defined) can be used for IPIs. The node identifier fits within the Intel-defined portion of the APICID register.

- x2apic-uv mode. In this mode, the APICIDs on each node have unique IDs, but IDs on different node are not unique. For example, if each mode has 32 cpus, the APICIDs on each node might be 0 - 31. Every node has the same set of IDs.
The UV hub is used to route IPIs/interrupts to the correct node. Traditional APIC operations WILL NOT WORK.

In x2apic-uv mode, the ACPI tables all contain a full unique ID (note:
exact bit layout still changing but the following is close):

nnnnnnnnnnlc0cch
n = unique node number
l = socket number on board
c = core
h = hyperthread

Only the "lc0cch" bits are written to the APICID register. The remaining bits are supplied by having the get_apic_id() function "OR" the extra bits into the value read from the APICID register. (Hmmm.. why not keep the ENTIRE APICID register in per-cpu data....)

The x2apic-uv mode is recognized by the MADT table containing:

	  oem_id = "SGI"
	  oem_table_id = "UV-X"

Based on:

        git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
---
 arch/x86/kernel/Makefile         |    2 
 arch/x86/kernel/apic_64.c        |    2 
 arch/x86/kernel/genapic_64.c     |   18 ++
 arch/x86/kernel/genx2apic_uv_x.c |  245 +++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup64.c        |    4 
 arch/x86/kernel/smpboot.c        |    5 
 include/asm-x86/genapic_64.h     |    5 
 include/asm-x86/smp.h            |    5 
 8 files changed, 285 insertions(+), 1 deletion(-)
arch/x86/kernel/genapic_64.c +18 -0
Index: linux/arch/x86/kernel/genapic_64.c
===================================================================
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
+#include <linux/hardirq.h>
 
 #include <asm/smp.h>
 #include <asm/ipi.h>
@@ -32,6 +33,7 @@ void *x86_cpu_to_apicid_early_ptr;
 #endif
 DEFINE_PER_CPU(u16, x86_cpu_to_apicid) = BAD_APICID;
 EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 struct genapic __read_mostly *genapic = &apic_flat;
 
@@ -42,6 +44,9 @@ static enum uv_system_type uv_system_typ
  */
 void __init setup_apic_routing(void)
 {
+	if (uv_system_type == UV_NON_UNIQUE_APIC)
+		genapic = &apic_x2apic_uv_x;
+	else
 #ifdef CONFIG_ACPI
 	/*
 	 * Quirk: some x86_64 machines can only use physical APIC mode
@@ -82,6 +87,19 @@ int __init acpi_madt_oem_check(char *oem
 	return 0;
 }
 
+unsigned int read_apic_id(void)
+{
+	unsigned int id;
+
+	WARN_ON(preemptible());
+	id = apic_read(APIC_ID);
+	if (uv_system_type >= UV_X2APIC)
+		id  |= __get_cpu_var(x2apic_extra_bits);
+	else
+		id = (id >> 24) & 0xFFu;;
+	return id;
+}
+
 enum uv_system_type get_uv_system_type(void)
 {
 	return uv_system_type;
arch/x86/kernel/genx2apic_uv_x.c new file +245 -0

245 lines not on this page · raw message

arch/x86/kernel/setup64.c +4 -0
Index: linux/arch/x86/kernel/setup64.c
===================================================================
@@ -24,6 +24,7 @@
 #include <asm/proto.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
+#include <asm/genapic.h>
 
 #ifndef CONFIG_DEBUG_BOOT_PARAMS
 struct boot_params __initdata boot_params;
@@ -280,4 +281,7 @@ void __cpuinit cpu_init (void)
 	fpu_init(); 
 
 	raw_local_save_flags(kernel_eflags);
+
+	if (is_uv_system())
+		uv_cpu_init();
 }
arch/x86/kernel/Makefile +1 -1
Index: linux/arch/x86/kernel/Makefile
===================================================================
@@ -97,7 +97,7 @@ obj-$(CONFIG_KMEMCHECK)		+= kmemcheck_32
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
-        obj-y				+= genapic_64.o genapic_flat_64.o
+        obj-y				+= genapic_64.o genapic_flat_64.o genx2apic_uv_x.o
         obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
         obj-$(CONFIG_AUDIT)		+= audit_64.o
 
include/asm-x86/genapic_64.h +5 -0
Index: linux/include/asm-x86/genapic_64.h
===================================================================
@@ -39,4 +39,9 @@ enum uv_system_type {UV_NONE, UV_LEGACY_
 extern enum uv_system_type get_uv_system_type(void);
 extern int is_uv_system(void);
 
+extern struct genapic apic_x2apic_uv_x;
+DECLARE_PER_CPU(int, x2apic_extra_bits);
+extern void uv_cpu_init(void);
+extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
+
 #endif
arch/x86/kernel/apic_64.c +2 -0
Index: linux/arch/x86/kernel/apic_64.c
===================================================================
@@ -738,6 +738,7 @@ void __cpuinit setup_local_APIC(void)
 	unsigned int value;
 	int i, j;
 
+	preempt_disable();
 	value = apic_read(APIC_LVR);
 
 	BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
@@ -831,6 +832,7 @@ void __cpuinit setup_local_APIC(void)
 	else
 		value = APIC_DM_NMI | APIC_LVT_MASKED;
 	apic_write(APIC_LVT1, value);
+	preempt_enable();
 }
 
 void __cpuinit lapic_setup_esr(void)
arch/x86/kernel/smpboot.c +5 -0
Index: linux/arch/x86/kernel/smpboot.c
===================================================================
@@ -1101,6 +1101,7 @@ static __init void disable_smp(void)
  */
 static int __init smp_sanity_check(unsigned max_cpus)
 {
+	preempt_disable();
 	if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
 		printk(KERN_WARNING "weird, boot CPU (#%d) not listed"
 				    "by the BIOS.\n", hard_smp_processor_id());
@@ -1112,6 +1113,7 @@ static int __init smp_sanity_check(unsig
 	 * get out of here now!
 	 */
 	if (!smp_found_config && !acpi_lapic) {
+		preempt_enable();
 		printk(KERN_NOTICE "SMP motherboard not detected.\n");
 		disable_smp();
 		if (APIC_init_uniprocessor())
@@ -1130,6 +1132,7 @@ static int __init smp_sanity_check(unsig
 			boot_cpu_physical_apicid);
 		physid_set(hard_smp_processor_id(), phys_cpu_present_map);
 	}
+	preempt_enable();
 
 	/*
 	 * If we couldn't find a local APIC, then get out of here now!
@@ -1205,11 +1208,13 @@ void __init native_smp_prepare_cpus(unsi
 		return;
 	}
 
+	preempt_disable();
 	if (GET_APIC_ID(read_apic_id()) != boot_cpu_physical_apicid) {
 		panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
 		     GET_APIC_ID(read_apic_id()), boot_cpu_physical_apicid);
 		/* Or can we switch back to PIC here? */
 	}
+	preempt_enable();
 
 #ifdef CONFIG_X86_32
 	connect_bsp_APIC();
include/asm-x86/smp.h +5 -0
Index: linux/include/asm-x86/smp.h
===================================================================
@@ -179,10 +179,15 @@ static inline int logical_smp_processor_
 	return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR));
 }
 
+#ifdef CONFIG_X86_32_SMP
 static inline unsigned int read_apic_id(void)
 {
 	return *(u32 *)(APIC_BASE + APIC_ID);
 }
+#else
+extern unsigned int read_apic_id(void);
+#endif
+
 
 # ifdef APIC_DEFINITION
 extern int hard_smp_processor_id(void);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#1 lore raw
Quoted 13 lines · Jack Steiner

Index: linux/arch/x86/kernel/apic_64.c
===================================================================

arch/x86/kernel/apic_64.c +1 -0
@@ -738,6 +738,7 @@ void __cpuinit setup_local_APIC(void)
 	unsigned int value;
 	int i, j;
 
+	preempt_disable();
 	value = apic_read(APIC_LVR);
 
 	BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);

arch/x86/kernel/apic_64.c void __cpuinit setup_local_APIC(void) · line 836

Quoted 5 lines
arch/x86/kernel/apic_64.c +1 -0
@@ -831,6 +832,7 @@ void __cpuinit setup_local_APIC(void)
 	else
 		value = APIC_DM_NMI | APIC_LVT_MASKED;
 	apic_write(APIC_LVT1, value);
+	preempt_enable();
 }

hm, this looks a bit weird - why are all the preempt-disable/enable calls needed?

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw
Quoted 14 lines · Ingo Molnar
Quoted 11 lines · Jack Steiner

Index: linux/arch/x86/kernel/apic_64.c
===================================================================

arch/x86/kernel/apic_64.c +1 -0
@@ -738,6 +738,7 @@ void __cpuinit setup_local_APIC(void)
 	unsigned int value;
 	int i, j;
 
+	preempt_disable();
 	value = apic_read(APIC_LVR);
 
Quoted 10 lines

arch/x86/kernel/apic_64.c void __cpuinit setup_local_APIC(void) · line 836

Quoted 7 lines
arch/x86/kernel/apic_64.c +1 -0
 	BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
@@ -831,6 +832,7 @@ void __cpuinit setup_local_APIC(void)
 	else
 		value = APIC_DM_NMI | APIC_LVT_MASKED;
 	apic_write(APIC_LVT1, value);
+	preempt_enable();
 }

hm, this looks a bit weird - why are all the preempt-disable/enable calls needed?

The first patch had a preempt disable/enable in the function that reads apicid (see read_apic_id() in arch/x86/kernel/genapic_64.c). This seemed necessary since large system generate an apicid by reading the live id & concatenating it with extra bits.

One of the review comments suggested that I change the preempt to a WARN() since reading apic_id really should be done with preemtion disabled. The added code eliminates the warnings.

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
Quoted 26 lines · Jack Steiner
Quoted 14 lines · Ingo Molnar
Quoted 11 lines · Jack Steiner

Index: linux/arch/x86/kernel/apic_64.c
===================================================================

arch/x86/kernel/apic_64.c +1 -0
@@ -738,6 +738,7 @@ void __cpuinit setup_local_APIC(void)
 	unsigned int value;
 	int i, j;
 
+	preempt_disable();
 	value = apic_read(APIC_LVR);
 
Quoted 10 lines

arch/x86/kernel/apic_64.c void __cpuinit setup_local_APIC(void) · line 836

Quoted 7 lines
arch/x86/kernel/apic_64.c +1 -0
 	BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
@@ -831,6 +832,7 @@ void __cpuinit setup_local_APIC(void)
 	else
 		value = APIC_DM_NMI | APIC_LVT_MASKED;
 	apic_write(APIC_LVT1, value);
+	preempt_enable();
 }

hm, this looks a bit weird - why are all the preempt-disable/enable calls needed?

Quoted 8 lines

The first patch had a preempt disable/enable in the function that reads apicid (see read_apic_id() in arch/x86/kernel/genapic_64.c). This seemed necessary since large system generate an apicid by reading the live id & concatenating it with extra bits.

One of the review comments suggested that I change the preempt to a WARN() since reading apic_id really should be done with preemtion disabled. The added code eliminates the warnings.

could you post the stacktraces of the warnings as they occured? All those codepaths should be running with preemption disabled in some natural way.

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#4 lore raw
Quoted 38 lines · Ingo Molnar
Quoted 26 lines · Jack Steiner
Quoted 14 lines · Ingo Molnar
Quoted 11 lines · Jack Steiner

Index: linux/arch/x86/kernel/apic_64.c
===================================================================

arch/x86/kernel/apic_64.c +1 -0
@@ -738,6 +738,7 @@ void __cpuinit setup_local_APIC(void)
 	unsigned int value;
 	int i, j;
 
+	preempt_disable();
 	value = apic_read(APIC_LVR);
 
Quoted 10 lines

arch/x86/kernel/apic_64.c void __cpuinit setup_local_APIC(void) · line 836

Quoted 7 lines
arch/x86/kernel/apic_64.c +1 -0
 	BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
@@ -831,6 +832,7 @@ void __cpuinit setup_local_APIC(void)
 	else
 		value = APIC_DM_NMI | APIC_LVT_MASKED;
 	apic_write(APIC_LVT1, value);
+	preempt_enable();
 }

hm, this looks a bit weird - why are all the preempt-disable/enable calls needed?

Quoted 8 lines

The first patch had a preempt disable/enable in the function that reads apicid (see read_apic_id() in arch/x86/kernel/genapic_64.c). This seemed necessary since large system generate an apicid by reading the live id & concatenating it with extra bits.

One of the review comments suggested that I change the preempt to a WARN() since reading apic_id really should be done with preemtion disabled. The added code eliminates the warnings.

Quoted 5 lines

could you post the stacktraces of the warnings as they occured? All those codepaths should be running with preemption disabled in some natural way.

Ingo

Here is one of the pathes. I have not been able to reproduce the other (smp_sanity_check()). It's possible there was cleanup that eliminated the message, or I might have forgotten the receipe. I know it was early in boot:

WARNING: at arch/x86/kernel/genapic_64.c:97 read_apic_id+0x30/0x6a()
Modules linked in:

Pid: 1, comm: swapper Not tainted 2.6.25-rc7-x86-latest.git-00829-gfb5f592-dirty #15

Call Trace:
 [<ffffffff80231e69>] warn_on_slowpath+0x51/0x63
 [<ffffffff80578d37>] _spin_lock+0xe/0x24
 [<ffffffff8022b289>] task_rq_lock+0x3d/0x6f
 [<ffffffff80579133>] _spin_unlock_irqrestore+0x12/0x2c
 [<ffffffff8022d7fd>] set_cpus_allowed+0xd9/0xe6
 [<ffffffff8057319c>] set_cpu_sibling_map+0x2f4/0x30c
 [<ffffffff8021f434>] read_apic_id+0x30/0x6a
 [<ffffffff807cf898>] native_smp_prepare_cpus+0xc4/0x2d4
 [<ffffffff807c580f>] kernel_init+0x4e/0x2cb
 [<ffffffff8020bee8>] child_rip+0xa/0x12

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw
In reply to Jack Steiner
Quoted 94 lines · Jack Steiner

UV supports really big systems. So big, in fact, that the APICID register does not contain enough bits to contain an APICID that is unique across all cpus.

The UV BIOS supports 3 APICID modes:

- legacy mode. This mode uses the old APIC mode where APICID is in bits [31:24] of the APICID register.

- x2apic mode. This mode is whitebox-compatible. APICIDs are unique across all cpus. Standard x2apic APIC operations (Intel-defined) can be used for IPIs. The node identifier fits within the Intel-defined portion of the APICID register.

- x2apic-uv mode. In this mode, the APICIDs on each node have unique IDs, but IDs on different node are not unique. For example, if each mode has 32 cpus, the APICIDs on each node might be 0 - 31. Every node has the same set of IDs.
The UV hub is used to route IPIs/interrupts to the correct node. Traditional APIC operations WILL NOT WORK.

In x2apic-uv mode, the ACPI tables all contain a full unique ID (note:
exact bit layout still changing but the following is close):

nnnnnnnnnnlc0cch
n = unique node number
l = socket number on board
c = core
h = hyperthread

Only the "lc0cch" bits are written to the APICID register. The remaining bits are supplied by having the get_apic_id() function "OR" the extra bits into the value read from the APICID register. (Hmmm.. why not keep the ENTIRE APICID register in per-cpu data....)

The x2apic-uv mode is recognized by the MADT table containing:

          oem_id = "SGI"
          oem_table_id = "UV-X"

Based on:

        git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git

---

  arch/x86/kernel/Makefile         |    2
  arch/x86/kernel/apic_64.c        |    2
  arch/x86/kernel/genapic_64.c     |   18 ++
  arch/x86/kernel/genx2apic_uv_x.c |  245 +++++++++++++++++++++++++++++++++++++++
  arch/x86/kernel/setup64.c        |    4
  arch/x86/kernel/smpboot.c        |    5
  include/asm-x86/genapic_64.h     |    5
  include/asm-x86/smp.h            |    5
  8 files changed, 285 insertions(+), 1 deletion(-)

Index: linux/arch/x86/kernel/genapic_64.c
===================================================================
--- linux.orig/arch/x86/kernel/genapic_64.c 2008-03-28 13:06:07.000000000 -0500
+++ linux/arch/x86/kernel/genapic_64.c 2008-03-28 13:06:12.000000000 -0500 @@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/init.h>
+#include <linux/hardirq.h>

#include <asm/smp.h>
#include <asm/ipi.h>
@@ -32,6 +33,7 @@ void *x86_cpu_to_apicid_early_ptr;
#endif
DEFINE_PER_CPU(u16, x86_cpu_to_apicid) = BAD_APICID; EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+DEFINE_PER_CPU(int, x2apic_extra_bits);

  struct genapic __read_mostly *genapic = &apic_flat;

@@ -42,6 +44,9 @@ static enum uv_system_type uv_system_typ
*/
void __init setup_apic_routing(void)
{
+ if (uv_system_type == UV_NON_UNIQUE_APIC)
+ genapic = &apic_x2apic_uv_x;
+ else
#ifdef CONFIG_ACPI
/*
* Quirk: some x86_64 machines can only use physical APIC mode
@@ -82,6 +87,19 @@ int __init acpi_madt_oem_check(char *oem

        return 0;

}

+unsigned int read_apic_id(void)
+{
+ unsigned int id;
+

Quoted 8 lines
 +       WARN_ON(preemptible());
 +       id = apic_read(APIC_ID);
 +       if (uv_system_type >= UV_X2APIC)

+ id |= __get_cpu_var(x2apic_extra_bits);
+ else
+ id = (id >> 24) & 0xFFu;;
+ return id;
+}

so this is "the new one of Friday"?

it still wrong. you can not shit id here. ot broke all x86_64 smp.

Did you test it on non UV_X2APIC box?

YH

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#6 lore raw
Quoted 105 lines · Yinghai Lu
Quoted 94 lines · Jack Steiner

UV supports really big systems. So big, in fact, that the APICID register does not contain enough bits to contain an APICID that is unique across all cpus.

The UV BIOS supports 3 APICID modes:

- legacy mode. This mode uses the old APIC mode where APICID is in bits [31:24] of the APICID register.

- x2apic mode. This mode is whitebox-compatible. APICIDs are unique across all cpus. Standard x2apic APIC operations (Intel-defined) can be used for IPIs. The node identifier fits within the Intel-defined portion of the APICID register.

- x2apic-uv mode. In this mode, the APICIDs on each node have unique IDs, but IDs on different node are not unique. For example, if each mode has 32 cpus, the APICIDs on each node might be 0 - 31. Every node has the same set of IDs.
The UV hub is used to route IPIs/interrupts to the correct node. Traditional APIC operations WILL NOT WORK.

In x2apic-uv mode, the ACPI tables all contain a full unique ID (note:
exact bit layout still changing but the following is close):

nnnnnnnnnnlc0cch
n = unique node number
l = socket number on board
c = core
h = hyperthread

Only the "lc0cch" bits are written to the APICID register. The remaining bits are supplied by having the get_apic_id() function "OR" the extra bits into the value read from the APICID register. (Hmmm.. why not keep the ENTIRE APICID register in per-cpu data....)

The x2apic-uv mode is recognized by the MADT table containing:

          oem_id = "SGI"
          oem_table_id = "UV-X"

Based on:

        git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git

---

  arch/x86/kernel/Makefile         |    2
  arch/x86/kernel/apic_64.c        |    2
  arch/x86/kernel/genapic_64.c     |   18 ++
  arch/x86/kernel/genx2apic_uv_x.c |  245 +++++++++++++++++++++++++++++++++++++++
  arch/x86/kernel/setup64.c        |    4
  arch/x86/kernel/smpboot.c        |    5
  include/asm-x86/genapic_64.h     |    5
  include/asm-x86/smp.h            |    5
  8 files changed, 285 insertions(+), 1 deletion(-)

Index: linux/arch/x86/kernel/genapic_64.c
===================================================================
--- linux.orig/arch/x86/kernel/genapic_64.c 2008-03-28 13:06:07.000000000 -0500
+++ linux/arch/x86/kernel/genapic_64.c 2008-03-28 13:06:12.000000000 -0500 @@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/init.h>
+#include <linux/hardirq.h>

#include <asm/smp.h>
#include <asm/ipi.h>
@@ -32,6 +33,7 @@ void *x86_cpu_to_apicid_early_ptr;
#endif
DEFINE_PER_CPU(u16, x86_cpu_to_apicid) = BAD_APICID; EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+DEFINE_PER_CPU(int, x2apic_extra_bits);

  struct genapic __read_mostly *genapic = &apic_flat;

@@ -42,6 +44,9 @@ static enum uv_system_type uv_system_typ
*/
void __init setup_apic_routing(void)
{
+ if (uv_system_type == UV_NON_UNIQUE_APIC)
+ genapic = &apic_x2apic_uv_x;
+ else
#ifdef CONFIG_ACPI
/*
* Quirk: some x86_64 machines can only use physical APIC mode
@@ -82,6 +87,19 @@ int __init acpi_madt_oem_check(char *oem

        return 0;

}

+unsigned int read_apic_id(void)
+{
+ unsigned int id;
+

Quoted 8 lines
 +       WARN_ON(preemptible());
 +       id = apic_read(APIC_ID);
 +       if (uv_system_type >= UV_X2APIC)

+ id |= __get_cpu_var(x2apic_extra_bits);
+ else
+ id = (id >> 24) & 0xFFu;;
+ return id;
+}

Quoted 5 lines

so this is "the new one of Friday"?

it still wrong. you can not shit id here. ot broke all x86_64 smp.

Did you test it on non UV_X2APIC box?

anyway the read_apic_id is totally wrong, even for your UV_X2APIC box. because id=apic_read(APIC_ID) will have apic_id at bits [31,24], and id |= __get_cpu_var(x2apic_extra_bits) is assuming that is on bits [5,0]

so you even didn't test in your UV_X2APIC box!

YH

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw
Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

anyway the read_apic_id is totally wrong, even for your UV_X2APIC box. because id=apic_read(APIC_ID) will have apic_id at bits [31,24], and id |= __get_cpu_var(x2apic_extra_bits) is assuming that is on bits [5,0]

so you even didn't test in your UV_X2APIC box!

It works fine on UV_X2APIX boxes because the double shift does not occur. However, support for UV_X2APIC is dependent on x2apic code that is not yet in the tree. Once the APIC is switched into x2apic mode, the apicid is located in the LOW bits of the apicid register, not the HIGH bits.

I have a local x2apic patch that I apply on top of the previous patches. The local patch is an early copy of a patch that will come from Intel. However, the other 2 apic modes work fine with the patches that were submitted.

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#8 lore raw
Quoted 6 lines · Jack Steiner
Quoted 6 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

anyway the read_apic_id is totally wrong, even for your UV_X2APIC box. because id=apic_read(APIC_ID) will have apic_id at bits [31,24], and id |= __get_cpu_var(x2apic_extra_bits) is assuming that is on bits [5,0]

Quoted 8 lines
Quoted 2 lines

so you even didn't test in your UV_X2APIC box!

It works fine on UV_X2APIX boxes because the double shift does not occur. However, support for UV_X2APIC is dependent on x2apic code that is not yet in the tree. Once the APIC is switched into x2apic mode, the apicid is located in the LOW bits of the apicid register, not the HIGH bits.

oh, so that will need have new version GET_APIC_ID too.

YH

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#9 lore raw
Quoted 10 lines · Yinghai Lu
Quoted 9 lines · Jack Steiner
Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

anyway the read_apic_id is totally wrong, even for your UV_X2APIC box. because id=apic_read(APIC_ID) will have apic_id at bits [31,24], and id |= __get_cpu_var(x2apic_extra_bits) is assuming that is on bits [5,0]

so you even didn't test in your UV_X2APIC box!

Quoted 7 lines
Quoted 5 lines

It works fine on UV_X2APIX boxes because the double shift does not occur. However, support for UV_X2APIC is dependent on x2apic code that is not yet in the tree. Once the APIC is switched into x2apic mode, the apicid is located in the LOW bits of the apicid register, not the HIGH bits.

oh, so that will need have new version GET_APIC_ID too.

Yes, although I think all the changes will be unified into one non-inline function that is a combination of GET_APIC_ID() & read_apic_id().

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw
Quoted 18 lines · Jack Steiner
Quoted 16 lines · Yinghai Lu
Quoted 14 lines · Jack Steiner
Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

anyway the read_apic_id is totally wrong, even for your UV_X2APIC box. because id=apic_read(APIC_ID) will have apic_id at bits [31,24], and id |= __get_cpu_var(x2apic_extra_bits) is assuming that is on bits [5,0]

so you even didn't test in your UV_X2APIC box!

It works fine on UV_X2APIX boxes because the double shift does not occur. However, support for UV_X2APIC is dependent on x2apic code that is not yet in the tree. Once the APIC is switched into x2apic mode, the apicid is located in the LOW bits of the apicid register, not the HIGH bits.

Quoted 5 lines
Quoted 1 line

oh, so that will need have new version GET_APIC_ID too.

Yes, although I think all the changes will be unified into one non-inline function that is a combination of GET_APIC_ID() & read_apic_id().

it seems x2apic patch should be applied before uv patch...

YH

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#11 lore raw
Quoted 21 lines · Yinghai Lu
Quoted 20 lines · Jack Steiner
Quoted 17 lines · Yinghai Lu
Quoted 6 lines · Jack Steiner
Quoted 6 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

anyway the read_apic_id is totally wrong, even for your UV_X2APIC box. because id=apic_read(APIC_ID) will have apic_id at bits [31,24], and id |= __get_cpu_var(x2apic_extra_bits) is assuming that is on bits [5,0]

Quoted 8 lines
Quoted 2 lines

so you even didn't test in your UV_X2APIC box!

It works fine on UV_X2APIX boxes because the double shift does not occur. However, support for UV_X2APIC is dependent on x2apic code that is not yet in the tree. Once the APIC is switched into x2apic mode, the apicid is located in the LOW bits of the apicid register, not the HIGH bits.

oh, so that will need have new version GET_APIC_ID too.

Quoted 7 lines
Quoted 3 lines

Yes, although I think all the changes will be unified into one non-inline function that is a combination of GET_APIC_ID() & read_apic_id().

it seems x2apic patch should be applied before uv patch...

YH

That was the original plan but the x2apic code, although functional, is not yet ready to be integrated. (This was mentioned as an outstanding issue in the patch on Friday).

Once the x2apic patch is applied, there will be one additional trivial UV patch (currently 1-line) that will be required to make UV_X2APIX fully functional. Since the other 2 UV apic modes are working right now, I decided not to wait for the x2apic patch before submitting the patches for the basic UV infrastructure.

We have a lot of code that is queued up waiting for the basic UV infrastructure to be integrated.

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw
In reply to Yinghai Lu
Quoted 1 line

so this is "the new one of Friday"?

Yes, and it has the same bug although it is located in a slightly different place.

A few minutes ago, I posted a patch to delete the extra lines.

Quoted 1 line

Did you test it on non UV_X2APIC box?

The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables. However, the bug does affect numa node assignment. And probably other places, too.

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#13 lore raw
Quoted 9 lines · Jack Steiner
Quoted 1 line

so this is "the new one of Friday"?

Yes, and it has the same bug although it is located in a slightly different place.

A few minutes ago, I posted a patch to delete the extra lines.

Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables. However, the bug does affect numa node assignment. And probably other places, too.

please consider one global get_apic_id() and bad_apicid to replace GET_APIC_ID and BAD_APICID at this point.

YH

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#14 lore raw
Quoted 19 lines · Yinghai Lu
Quoted 9 lines · Jack Steiner
Quoted 1 line

so this is "the new one of Friday"?

Yes, and it has the same bug although it is located in a slightly different place.

A few minutes ago, I posted a patch to delete the extra lines.

Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables. However, the bug does affect numa node assignment. And probably other places, too.

Quoted 2 lines

please consider one global get_apic_id() and bad_apicid to replace GET_APIC_ID and BAD_APICID at this point.

I think that makes sense.

The x2apic patch that should be posted in the near future also makes significant changes in this area. Once that patch is posted, I'll make the simplifications.

Ok???

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#15 lore raw
Quoted 24 lines · Jack Steiner
Quoted 19 lines · Yinghai Lu
Quoted 9 lines · Jack Steiner
Quoted 1 line

so this is "the new one of Friday"?

Yes, and it has the same bug although it is located in a slightly different place.

A few minutes ago, I posted a patch to delete the extra lines.

Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables. However, the bug does affect numa node assignment. And probably other places, too.

Quoted 2 lines

please consider one global get_apic_id() and bad_apicid to replace GET_APIC_ID and BAD_APICID at this point.

Quoted 7 lines

I think that makes sense.

The x2apic patch that should be posted in the near future also makes significant changes in this area. Once that patch is posted, I'll make the simplifications.

Ok???

good.

with the x2apic patch, GET_APIC_ID is read_apic_id, and it will not shift again?

YH

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#16 lore raw
Quoted 31 lines · Yinghai Lu
Quoted 30 lines · Jack Steiner
Quoted 19 lines · Yinghai Lu
Quoted 9 lines · Jack Steiner
Quoted 1 line

so this is "the new one of Friday"?

Yes, and it has the same bug although it is located in a slightly different place.

A few minutes ago, I posted a patch to delete the extra lines.

Quoted 8 lines
Quoted 1 line

Did you test it on non UV_X2APIC box?

The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables. However, the bug does affect numa node assignment. And probably other places, too.

Quoted 2 lines

please consider one global get_apic_id() and bad_apicid to replace GET_APIC_ID and BAD_APICID at this point.

I think that makes sense.

The x2apic patch that should be posted in the near future also makes significant changes in this area. Once that patch is posted, I'll make the simplifications.

Quoted 7 lines
Quoted 1 line

Ok???

good.

with the x2apic patch, GET_APIC_ID is read_apic_id, and it will not shift again?

YH

Right....

--- jack

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#17 lore raw

Re: [PATCH 8/8] x86_64: V2 Support for new UV apic

In reply to Jack Steiner

Fix double-shift of apicid in previous patch.

---
The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables.

 arch/x86/kernel/genapic_64.c |    2 --
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/genapic_64.c +0 -2
Index: linux/arch/x86/kernel/genapic_64.c
===================================================================
@@ -98,8 +98,6 @@ unsigned int read_apic_id(void)
 	id = apic_read(APIC_ID);
 	if (uv_system_type >= UV_X2APIC)
 		id  |= __get_cpu_var(x2apic_extra_bits);
-	else
-		id = (id >> 24) & 0xFFu;;
 	return id;
 }
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#18 lore raw

Re: [PATCH 8/8] x86_64: V2 Support for new UV apic

Quoted 6 lines · Jack Steiner

Fix double-shift of apicid in previous patch.

The code is clearly wrong. I booted on an 8p AMD box and had no problems. Apparently the kernel (at least basic booting) is not too sensitive to incorrect apicids being returned. Most critical-to-boot code must use apicids from the ACPI tables.

yeah - patch added. Thanks Yinghai for persisting on this.

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>