Skip to contentSkip to conversation

x86: add apic probe for genapic 64bit

PATCH New Yinghai Lu 4 participants 17 messages Jul 22, 2008 – Jul 26, 2008 x86

lore
Share & tools
lore

Yinghai Lu

author
#0 lore raw

PATCH 1/1 x86: add apic probe for genapic 64bit

so remove uv, x2apic related code from genapic_64.c to their specific genapic files

---
 arch/x86/kernel/genapic_64.c        |   87 +++++++++++-------------------------
 arch/x86/kernel/genapic_flat_64.c   |   24 +++++++++
 arch/x86/kernel/genx2apic_cluster.c |   11 ++++
 arch/x86/kernel/genx2apic_phys.c    |   21 ++++++++
 arch/x86/kernel/genx2apic_uv_x.c    |   32 ++++++++++++-
 include/asm-x86/genapic_64.h        |    1 
 6 files changed, 115 insertions(+), 61 deletions(-)
arch/x86/kernel/genapic_64.c +27 -60
Index: linux-2.6/arch/x86/kernel/genapic_64.c
===================================================================
@@ -16,62 +16,37 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/hardirq.h>
-#include <linux/dmar.h>
 
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
-#ifdef CONFIG_ACPI
-#include <acpi/acpi_bus.h>
-#endif
-
-DEFINE_PER_CPU(int, x2apic_extra_bits);
+extern struct genapic apic_flat;
+extern struct genapic apic_physflat;
+extern struct genapic apic_x2xpic_uv_x;
+extern struct genapic apic_x2apic_phys;
+extern struct genapic apic_x2apic_cluster;
 
 struct genapic __read_mostly *genapic = &apic_flat;
 
-static int x2apic_phys = 0;
-
-static int set_x2apic_phys_mode(char *arg)
-{
-	x2apic_phys = 1;
-	return 0;
-}
-early_param("x2apic_phys", set_x2apic_phys_mode);
-
-static enum uv_system_type uv_system_type;
+static struct genapic *apic_probe[] __initdata = {
+        &apic_x2apic_uv_x,
+        &apic_x2apic_phys,
+        &apic_x2apic_cluster,
+        &apic_physflat,
+        NULL,
+};
 
 /*
  * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
  */
 void __init setup_apic_routing(void)
 {
-	if (uv_system_type == UV_NON_UNIQUE_APIC)
-		genapic = &apic_x2apic_uv_x;
-	else if (cpu_has_x2apic && intr_remapping_enabled) {
-		if (x2apic_phys)
-			genapic = &apic_x2apic_phys;
-		else
-			genapic = &apic_x2apic_cluster;
-	} else
-#ifdef CONFIG_ACPI
-	/*
-	 * Quirk: some x86_64 machines can only use physical APIC mode
-	 * regardless of how many processors are present (x86_64 ES7000
-	 * is an example).
-	 */
-	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
-			(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
-		genapic = &apic_physflat;
-	else
-#endif
-
-	if (max_physical_apicid < 8)
-		genapic = &apic_flat;
-	else
-		genapic = &apic_physflat;
-
-	printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+	if (genapic == &apic_flat) {
+		if (max_physical_apicid >= 8)
+			genapic = &apic_physflat;
+		printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+	}
 }
 
 /* Same for both flat and physical. */
@@ -83,23 +58,15 @@ void apic_send_IPI_self(int vector)
 
 int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	if (!strcmp(oem_id, "SGI")) {
-		if (!strcmp(oem_table_id, "UVL"))
-			uv_system_type = UV_LEGACY_APIC;
-		else if (!strcmp(oem_table_id, "UVX"))
-			uv_system_type = UV_X2APIC;
-		else if (!strcmp(oem_table_id, "UVH"))
-			uv_system_type = UV_NON_UNIQUE_APIC;
-	}
-	return 0;
-}
-
-enum uv_system_type get_uv_system_type(void)
-{
-	return uv_system_type;
-}
+        int i;
 
-int is_uv_system(void)
-{
-	return uv_system_type != UV_NONE;
+        for (i = 0; apic_probe[i]; ++i) {
+                if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
+			genapic = apic_probe[i];
+			printk(KERN_INFO "Setting APIC routing to %s.\n",
+                                       genapic->name);
+                        return 1;
+                }
+        }
+        return 0;
 }
arch/x86/kernel/genapic_flat_64.c +24 -0
Index: linux-2.6/arch/x86/kernel/genapic_flat_64.c
===================================================================
@@ -21,6 +21,15 @@
 #include <asm/genapic.h>
 #include <mach_apicdef.h>
 
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+#endif
+
+static int __init flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	return 1;
+}
+
 static cpumask_t flat_target_cpus(void)
 {
 	return cpu_online_map;
@@ -138,6 +147,7 @@ static unsigned int phys_pkg_id(int inde
 
 struct genapic apic_flat =  {
 	.name = "flat",
+	.acpi_madt_oem_check = flat_acpi_madt_oem_check,
 	.int_delivery_mode = dest_LowestPrio,
 	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
 	.target_cpus = flat_target_cpus,
@@ -160,6 +170,19 @@ struct genapic apic_flat =  {
  * We cannot use logical delivery in this case because the mask
  * overflows, so use physical mode.
  */
+static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	/*
+	 * Quirk: some x86_64 machines can only use physical APIC mode
+	 * regardless of how many processors are present (x86_64 ES7000
+	 * is an example).
+	 */
+	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
+		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
+		return 1;
+
+	return 0;
+}
 
 static cpumask_t physflat_target_cpus(void)
 {
@@ -206,6 +229,7 @@ static unsigned int physflat_cpu_mask_to
 
 struct genapic apic_physflat =  {
 	.name = "physical flat",
+	.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
 	.int_delivery_mode = dest_Fixed,
 	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 	.target_cpus = physflat_target_cpus,
arch/x86/kernel/genx2apic_cluster.c +11 -0
Index: linux-2.6/arch/x86/kernel/genx2apic_cluster.c
===================================================================
@@ -4,12 +4,22 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
+#include <linux/dmar.h>
+
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
 DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
 
+static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (cpu_has_x2apic && intr_remapping_enabled)
+		return 1;
+
+	return 0;
+}
+
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
 
 static cpumask_t x2apic_target_cpus(void)
@@ -135,6 +145,7 @@ static void init_x2apic_ldr(void)
 
 struct genapic apic_x2apic_cluster = {
 	.name = "cluster x2apic",
+	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
 	.int_delivery_mode = dest_LowestPrio,
 	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
 	.target_cpus = x2apic_target_cpus,
arch/x86/kernel/genx2apic_phys.c +21 -0
Index: linux-2.6/arch/x86/kernel/genx2apic_phys.c
===================================================================
@@ -4,10 +4,30 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
+#include <linux/dmar.h>
+
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
+DEFINE_PER_CPU(int, x2apic_extra_bits);
+
+static int x2apic_phys = 0;
+
+static int set_x2apic_phys_mode(char *arg)
+{
+	x2apic_phys = 1;
+	return 0;
+}
+early_param("x2apic_phys", set_x2apic_phys_mode);
+
+static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (cpu_has_x2apic && intr_remapping_enabled && x2apic_phys)
+		return 1;
+
+	return 0;
+}
 
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
 
@@ -122,6 +142,7 @@ void init_x2apic_ldr(void)
 
 struct genapic apic_x2apic_phys = {
 	.name = "physical x2apic",
+	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
 	.int_delivery_mode = dest_Fixed,
 	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 	.target_cpus = x2apic_target_cpus,
arch/x86/kernel/genx2apic_uv_x.c +31 -1
Index: linux-2.6/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
@@ -27,6 +27,33 @@
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/bios.h>
 
+static enum uv_system_type uv_system_type;
+
+static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (!strcmp(oem_id, "SGI")) {
+		if (!strcmp(oem_table_id, "UVL"))
+			uv_system_type = UV_LEGACY_APIC;
+		else if (!strcmp(oem_table_id, "UVX"))
+			uv_system_type = UV_X2APIC;
+		else if (!strcmp(oem_table_id, "UVH")) {
+			uv_system_type = UV_NON_UNIQUE_APIC;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+enum uv_system_type get_uv_system_type(void)
+{
+	return uv_system_type;
+}
+
+int is_uv_system(void)
+{
+	return uv_system_type != UV_NONE;
+}
+
 DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
 
@@ -153,7 +180,7 @@ static unsigned int get_apic_id(unsigned
 	return id;
 }
 
-static long set_apic_id(unsigned int id)
+static unsigned long set_apic_id(unsigned int id)
 {
 	unsigned long x;
 
@@ -182,6 +209,7 @@ static void uv_send_IPI_self(int vector)
 
 struct genapic apic_x2apic_uv_x = {
 	.name = "UV large system",
+	.acpi_madt_oem_check = uv_acpi_madt_oem_check,
 	.int_delivery_mode = dest_Fixed,
 	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 	.target_cpus = uv_target_cpus,
@@ -433,3 +461,5 @@ void __cpuinit uv_cpu_init(void)
 	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
 		set_x2apic_extra_bits(uv_hub_info->pnode);
 }
+
+
include/asm-x86/genapic_64.h +1 -0
Index: linux-2.6/include/asm-x86/genapic_64.h
===================================================================
@@ -14,6 +14,7 @@
 
 struct genapic {
 	char *name;
+	int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
 	u32 int_delivery_mode;
 	u32 int_dest_mode;
 	int (*apic_id_registered)(void);
author
#1 lore raw

PATCH 1/1 x86: add apic probe for genapic 64bit v2

so remove uv, x2apic related code from genapic_64.c to their specific genapic files

v2: fix compiling when CONFIG_ACPI is not set

---
 arch/x86/kernel/genapic_64.c        |   85 +++++++++++-------------------------
 arch/x86/kernel/genapic_flat_64.c   |   26 +++++++++++
 arch/x86/kernel/genx2apic_cluster.c |   11 ++++
 arch/x86/kernel/genx2apic_phys.c    |   21 ++++++++
 arch/x86/kernel/genx2apic_uv_x.c    |   32 +++++++++++++
 include/asm-x86/genapic_64.h        |    1 
 6 files changed, 116 insertions(+), 60 deletions(-)
arch/x86/kernel/genapic_64.c +26 -59
Index: linux-2.6/arch/x86/kernel/genapic_64.c
===================================================================
@@ -16,62 +16,37 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/hardirq.h>
-#include <linux/dmar.h>
 
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
-#ifdef CONFIG_ACPI
-#include <acpi/acpi_bus.h>
-#endif
-
-DEFINE_PER_CPU(int, x2apic_extra_bits);
+extern struct genapic apic_flat;
+extern struct genapic apic_physflat;
+extern struct genapic apic_x2xpic_uv_x;
+extern struct genapic apic_x2apic_phys;
+extern struct genapic apic_x2apic_cluster;
 
 struct genapic __read_mostly *genapic = &apic_flat;
 
-static int x2apic_phys = 0;
-
-static int set_x2apic_phys_mode(char *arg)
-{
-	x2apic_phys = 1;
-	return 0;
-}
-early_param("x2apic_phys", set_x2apic_phys_mode);
-
-static enum uv_system_type uv_system_type;
+static struct genapic *apic_probe[] __initdata = {
+	&apic_x2apic_uv_x,
+	&apic_x2apic_phys,
+	&apic_x2apic_cluster,
+	&apic_physflat,
+	NULL,
+};
 
 /*
  * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
  */
 void __init setup_apic_routing(void)
 {
-	if (uv_system_type == UV_NON_UNIQUE_APIC)
-		genapic = &apic_x2apic_uv_x;
-	else if (cpu_has_x2apic && intr_remapping_enabled) {
-		if (x2apic_phys)
-			genapic = &apic_x2apic_phys;
-		else
-			genapic = &apic_x2apic_cluster;
-	} else
-#ifdef CONFIG_ACPI
-	/*
-	 * Quirk: some x86_64 machines can only use physical APIC mode
-	 * regardless of how many processors are present (x86_64 ES7000
-	 * is an example).
-	 */
-	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
-			(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
-		genapic = &apic_physflat;
-	else
-#endif
-
-	if (max_physical_apicid < 8)
-		genapic = &apic_flat;
-	else
-		genapic = &apic_physflat;
-
-	printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+	if (genapic == &apic_flat) {
+		if (max_physical_apicid >= 8)
+			genapic = &apic_physflat;
+		printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+	}
 }
 
 /* Same for both flat and physical. */
@@ -83,23 +58,15 @@ void apic_send_IPI_self(int vector)
 
 int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	if (!strcmp(oem_id, "SGI")) {
-		if (!strcmp(oem_table_id, "UVL"))
-			uv_system_type = UV_LEGACY_APIC;
-		else if (!strcmp(oem_table_id, "UVX"))
-			uv_system_type = UV_X2APIC;
-		else if (!strcmp(oem_table_id, "UVH"))
-			uv_system_type = UV_NON_UNIQUE_APIC;
+	int i;
+
+	for (i = 0; apic_probe[i]; ++i) {
+		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
+			genapic = apic_probe[i];
+			printk(KERN_INFO "Setting APIC routing to %s.\n",
+				genapic->name);
+			return 1;
+		}
 	}
 	return 0;
 }
-
-enum uv_system_type get_uv_system_type(void)
-{
-	return uv_system_type;
-}
-
-int is_uv_system(void)
-{
-	return uv_system_type != UV_NONE;
-}
arch/x86/kernel/genapic_flat_64.c +26 -0
Index: linux-2.6/arch/x86/kernel/genapic_flat_64.c
===================================================================
@@ -21,6 +21,15 @@
 #include <asm/genapic.h>
 #include <mach_apicdef.h>
 
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+#endif
+
+static int __init flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	return 1;
+}
+
 static cpumask_t flat_target_cpus(void)
 {
 	return cpu_online_map;
@@ -138,6 +147,7 @@ static unsigned int phys_pkg_id(int inde
 
 struct genapic apic_flat =  {
 	.name = "flat",
+	.acpi_madt_oem_check = flat_acpi_madt_oem_check,
 	.int_delivery_mode = dest_LowestPrio,
 	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
 	.target_cpus = flat_target_cpus,
@@ -160,6 +170,21 @@ struct genapic apic_flat =  {
  * We cannot use logical delivery in this case because the mask
  * overflows, so use physical mode.
  */
+static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+#ifdef CONFIG_ACPI
+	/*
+	 * Quirk: some x86_64 machines can only use physical APIC mode
+	 * regardless of how many processors are present (x86_64 ES7000
+	 * is an example).
+	 */
+	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
+		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
+		return 1;
+#endif
+
+	return 0;
+}
 
 static cpumask_t physflat_target_cpus(void)
 {
@@ -206,6 +231,7 @@ static unsigned int physflat_cpu_mask_to
 
 struct genapic apic_physflat =  {
 	.name = "physical flat",
+	.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
 	.int_delivery_mode = dest_Fixed,
 	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 	.target_cpus = physflat_target_cpus,
arch/x86/kernel/genx2apic_cluster.c +11 -0
Index: linux-2.6/arch/x86/kernel/genx2apic_cluster.c
===================================================================
@@ -4,12 +4,22 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
+#include <linux/dmar.h>
+
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
 DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
 
+static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (cpu_has_x2apic && intr_remapping_enabled)
+		return 1;
+
+	return 0;
+}
+
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
 
 static cpumask_t x2apic_target_cpus(void)
@@ -135,6 +145,7 @@ static void init_x2apic_ldr(void)
 
 struct genapic apic_x2apic_cluster = {
 	.name = "cluster x2apic",
+	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
 	.int_delivery_mode = dest_LowestPrio,
 	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
 	.target_cpus = x2apic_target_cpus,
arch/x86/kernel/genx2apic_phys.c +21 -0
Index: linux-2.6/arch/x86/kernel/genx2apic_phys.c
===================================================================
@@ -4,10 +4,30 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
+#include <linux/dmar.h>
+
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
+DEFINE_PER_CPU(int, x2apic_extra_bits);
+
+static int x2apic_phys;
+
+static int set_x2apic_phys_mode(char *arg)
+{
+	x2apic_phys = 1;
+	return 0;
+}
+early_param("x2apic_phys", set_x2apic_phys_mode);
+
+static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (cpu_has_x2apic && intr_remapping_enabled && x2apic_phys)
+		return 1;
+
+	return 0;
+}
 
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
 
@@ -122,6 +142,7 @@ void init_x2apic_ldr(void)
 
 struct genapic apic_x2apic_phys = {
 	.name = "physical x2apic",
+	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
 	.int_delivery_mode = dest_Fixed,
 	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 	.target_cpus = x2apic_target_cpus,
arch/x86/kernel/genx2apic_uv_x.c +31 -1
Index: linux-2.6/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
@@ -27,6 +27,33 @@
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/bios.h>
 
+static enum uv_system_type uv_system_type;
+
+static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (!strcmp(oem_id, "SGI")) {
+		if (!strcmp(oem_table_id, "UVL"))
+			uv_system_type = UV_LEGACY_APIC;
+		else if (!strcmp(oem_table_id, "UVX"))
+			uv_system_type = UV_X2APIC;
+		else if (!strcmp(oem_table_id, "UVH")) {
+			uv_system_type = UV_NON_UNIQUE_APIC;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+enum uv_system_type get_uv_system_type(void)
+{
+	return uv_system_type;
+}
+
+int is_uv_system(void)
+{
+	return uv_system_type != UV_NONE;
+}
+
 DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
 
@@ -153,7 +180,7 @@ static unsigned int get_apic_id(unsigned
 	return id;
 }
 
-static long set_apic_id(unsigned int id)
+static unsigned long set_apic_id(unsigned int id)
 {
 	unsigned long x;
 
@@ -182,6 +209,7 @@ static void uv_send_IPI_self(int vector)
 
 struct genapic apic_x2apic_uv_x = {
 	.name = "UV large system",
+	.acpi_madt_oem_check = uv_acpi_madt_oem_check,
 	.int_delivery_mode = dest_Fixed,
 	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
 	.target_cpus = uv_target_cpus,
@@ -433,3 +461,5 @@ void __cpuinit uv_cpu_init(void)
 	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
 		set_x2apic_extra_bits(uv_hub_info->pnode);
 }
+
+
include/asm-x86/genapic_64.h +1 -0
Index: linux-2.6/include/asm-x86/genapic_64.h
===================================================================
@@ -14,6 +14,7 @@
 
 struct genapic {
 	char *name;
+	int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
 	u32 int_delivery_mode;
 	u32 int_dest_mode;
 	int (*apic_id_registered)(void);
Applied
#2 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 4 lines · Yinghai Lu

so remove uv, x2apic related code from genapic_64.c to their specific genapic files

v2: fix compiling when CONFIG_ACPI is not set

applied to tip/x86/x2apic - thanks Yinghai.

arch/x86/kernel/genapic_64.c line 38

Quoted 7 lines
arch/x86/kernel/genapic_64.c +7 -0
+static struct genapic *apic_probe[] __initdata = {
+	&apic_x2apic_uv_x,
+	&apic_x2apic_phys,
+	&apic_x2apic_cluster,
+	&apic_physflat,
+	NULL,
+};

very nice generalization!

Ingo

#3 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 4 lines · Ingo Molnar
Quoted 1 line

v2: fix compiling when CONFIG_ACPI is not set

applied to tip/x86/x2apic - thanks Yinghai.

Quoted 9 lines

arch/x86/kernel/genapic_64.c line 38

Quoted 7 lines
arch/x86/kernel/genapic_64.c +7 -0
+static struct genapic *apic_probe[] __initdata = {
+	&apic_x2apic_uv_x,
+	&apic_x2apic_phys,
+	&apic_x2apic_cluster,
+	&apic_physflat,
+	NULL,
+};

very nice generalization!

btw.:

apic_probe[i]->acpi_madt_oem_check

should probably be renamed to something more neutral like "->probe" - there's nothing ACPI about it and some weird boxes could use PCI or other probing mechanisms to discover the type of APIC they want to use.

plus i guess genapic_32.h and genapic_64.h should be unified and struct apic_ops should be put into struct genapic?

Ingo

author
#4 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 17 lines · Ingo Molnar
Quoted 4 lines · Ingo Molnar
Quoted 1 line

v2: fix compiling when CONFIG_ACPI is not set

applied to tip/x86/x2apic - thanks Yinghai.

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +7 -0
+static struct genapic *apic_probe[] __initdata = {
+   &apic_x2apic_uv_x,
+   &apic_x2apic_phys,
+   &apic_x2apic_cluster,
+   &apic_physflat,
+   NULL,
+};

very nice generalization!

Quoted 7 lines

btw.:

apic_probe[i]->acpi_madt_oem_check

should probably be renamed to something more neutral like "->probe" - there's nothing ACPI about it and some weird boxes could use PCI or other probing mechanisms to discover the type of APIC they want to use.

32bit has acpi_madt_oem_check and mps_oem_check
64bit should only have acpi_madt_oem_check

Quoted 3 lines

plus i guess genapic_32.h and genapic_64.h should be unified and struct apic_ops should be put into struct genapic?

yes.

hope to call acpi_madt_oem_check and mps_oem_check right after acpi_boot_table_init
to decide apic_ops and genapic as early as possible.

Jack/Mike,
does your big box support SRAT? it seems it calling is_uv_system before acpi_madt_oem_check is called.
I like to call early_acpi_boot_init, before acpi_numa_init so acpi_madt_oem_check is called before srat is used. can you check attached patch on your system?

YH

[PATCH] x86: call early_acpi_boot_init before acpi_numa_init

so could call acpi_madt_oem_check early to find out if it uv system. and acpi_numa_init could call is_uv_system()

---
 arch/x86/kernel/setup.c |    4 ++++
 1 file changed, 4 insertions(+)
arch/x86/kernel/setup.c +4 -0
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
@@ -785,6 +785,10 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_table_init();
 
 #ifdef CONFIG_ACPI_NUMA
+#ifdef CONFIG_X86_64
+	/* try to call acpi_madt_oem_check here */
+	early_acpi_boot_init();
+#endif
 	/*
 	 * Parse SRAT to discover nodes.
 	 */
#5 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 20 lines · Yinghai Lu
Quoted 19 lines · Ingo Molnar
Quoted 4 lines · Ingo Molnar
Quoted 1 line

v2: fix compiling when CONFIG_ACPI is not set

applied to tip/x86/x2apic - thanks Yinghai.

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +7 -0
+static struct genapic *apic_probe[] __initdata = {
+   &apic_x2apic_uv_x,
+   &apic_x2apic_phys,
+   &apic_x2apic_cluster,
+   &apic_physflat,
+   NULL,
+};

very nice generalization!

btw.:

Quoted 8 lines
Quoted 5 lines

apic_probe[i]->acpi_madt_oem_check

should probably be renamed to something more neutral like "->probe" - there's nothing ACPI about it and some weird boxes could use PCI or other probing mechanisms to discover the type of APIC they want to use.

32bit has acpi_madt_oem_check and mps_oem_check
64bit should only have acpi_madt_oem_check

yeah.

It's just a small detail: what i mean is that the method itself should eventually simply be renamed from "acpi_madt_oem_check" to "probe". There's nothing ACPI about this exept the fact that most current "is this the APIC driver we should be using" checks involve some sort of ACPI discovery. This is a Linux abstraction and as such a more generic name like "probe" sounds more appropriate.

Ingo

author
#6 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 32 lines · Ingo Molnar
Quoted 20 lines · Yinghai Lu
Quoted 19 lines · Ingo Molnar
Quoted 4 lines · Ingo Molnar
Quoted 1 line

v2: fix compiling when CONFIG_ACPI is not set

applied to tip/x86/x2apic - thanks Yinghai.

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +7 -0
+static struct genapic *apic_probe[] __initdata = {
+   &apic_x2apic_uv_x,
+   &apic_x2apic_phys,
+   &apic_x2apic_cluster,
+   &apic_physflat,
+   NULL,
+};

very nice generalization!

btw.:

Quoted 8 lines
Quoted 5 lines

apic_probe[i]->acpi_madt_oem_check

should probably be renamed to something more neutral like "->probe" - there's nothing ACPI about it and some weird boxes could use PCI or other probing mechanisms to discover the type of APIC they want to use.

32bit has acpi_madt_oem_check and mps_oem_check
64bit should only have acpi_madt_oem_check

Quoted 8 lines

yeah.

It's just a small detail: what i mean is that the method itself should eventually simply be renamed from "acpi_madt_oem_check" to "probe". There's nothing ACPI about this exept the fact that most current "is this the APIC driver we should be using" checks involve some sort of ACPI discovery. This is a Linux abstraction and as such a more generic name like "probe" sounds more appropriate.

OK

YH

#7 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

In reply to Yinghai Lu
Quoted 35 lines · Yinghai Lu
Quoted 13 lines · Ingo Molnar
Quoted 11 lines · Ingo Molnar
Quoted 1 line

v2: fix compiling when CONFIG_ACPI is not set

applied to tip/x86/x2apic - thanks Yinghai.

Review

Quoted 7 lines
(quoted diff) +7 -0
+static struct genapic *apic_probe[] __initdata = {
+   &apic_x2apic_uv_x,
+   &apic_x2apic_phys,
+   &apic_x2apic_cluster,
+   &apic_physflat,
+   NULL,
+};

very nice generalization!

Quoted 7 lines

btw.:

apic_probe[i]->acpi_madt_oem_check

should probably be renamed to something more neutral like "->probe" - there's nothing ACPI about it and some weird boxes could use PCI or other probing mechanisms to discover the type of APIC they want to use.

32bit has acpi_madt_oem_check and mps_oem_check
64bit should only have acpi_madt_oem_check

Quoted 2 lines

plus i guess genapic_32.h and genapic_64.h should be unified and struct apic_ops should be put into struct genapic?

yes.

hope to call acpi_madt_oem_check and mps_oem_check right after acpi_boot_table_init
to decide apic_ops and genapic as early as possible.

Quoted 9 lines

Jack/Mike,
does your big box support SRAT? it seems it calling is_uv_system before acpi_madt_oem_check is called.
I like to call early_acpi_boot_init, before acpi_numa_init so acpi_madt_oem_check is called before srat is used. can you check attached patch on your system?

YH

Hi,

Yes, I believe so though the final BIOS is not yet complete.

Next chance I get, I'll try out your patch.

Thanks,
Mike

#8 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

In reply to Yinghai Lu
Quoted 6 lines · Yinghai Lu

Index: linux-2.6/arch/x86/kernel/genapic_64.c
===================================================================

arch/x86/kernel/genapic_64.c +0 -1
-                       genapic = &apic_x2apic_cluster;

...

Quoted 11 lines
arch/x86/kernel/genapic_64.c +0 -11
-       } else
-#ifdef CONFIG_ACPI
-       /*
-        * Quirk: some x86_64 machines can only use physical APIC mode
-        * regardless of how many processors are present (x86_64 ES7000
-        * is an example).
-        */
-       if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
-                       (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
-               genapic = &apic_physflat;
-       else

arch/x86/kernel/genapic_64.c line 46

Quoted 10 lines
arch/x86/kernel/genapic_64.c +2 -8
-#endif
-
-       if (max_physical_apicid < 8)
-               genapic = &apic_flat;
-       else
-               genapic = &apic_physflat;
-
-       printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+       if (genapic == &apic_flat) {
+               if (max_physical_apicid >= 8)

Yinghai, though not directly realted to this probe cleanup, what is this 'max_physical_apicid' doing.

I don't understand the need for this commit.

Quoted 11 lines

commit e0da33646826b66ef933d47ea2fb7a693fd849bf

Author: Yinghai Lu <[email protected]>
Date:   Sun Jun 8 18:29:22 2008 -0700

x86: introduce max_physical_apicid for bigsmp switching

a multi-socket test-system with 3 or 4 ioapics, when 4 dualcore cpus or 2 quadcore cpus installed, needs to switch to bigsmp or physflat.

CPU apic id is [4,11] instead of [0,7], and we need to check max apic id instead of cpu numbers.

for logical flat, it really shouldn't matter how large the physical apic id is. In logical flat, OS programs the LDR and the limitation is the number of cpu's which is '8'.

What am I missing here?

thanks,
suresh

author
#9 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 45 lines · Suresh Siddha
Quoted 6 lines · Yinghai Lu

Index: linux-2.6/arch/x86/kernel/genapic_64.c
===================================================================

arch/x86/kernel/genapic_64.c +0 -1
-                       genapic = &apic_x2apic_cluster;

...

Quoted 11 lines
arch/x86/kernel/genapic_64.c +0 -11
-       } else
-#ifdef CONFIG_ACPI
-       /*
-        * Quirk: some x86_64 machines can only use physical APIC mode
-        * regardless of how many processors are present (x86_64 ES7000
-        * is an example).
-        */
-       if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
-                       (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
-               genapic = &apic_physflat;
-       else

arch/x86/kernel/genapic_64.c line 46

Quoted 10 lines
arch/x86/kernel/genapic_64.c +2 -8
-#endif
-
-       if (max_physical_apicid < 8)
-               genapic = &apic_flat;
-       else
-               genapic = &apic_physflat;
-
-       printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
+       if (genapic == &apic_flat) {
+               if (max_physical_apicid >= 8)

Yinghai, though not directly realted to this probe cleanup, what is this 'max_physical_apicid' doing.

I don't understand the need for this commit.

Quoted 9 lines

commit e0da33646826b66ef933d47ea2fb7a693fd849bf

Author: Yinghai Lu <[email protected]>
Date:   Sun Jun 8 18:29:22 2008 -0700

x86: introduce max_physical_apicid for bigsmp switching

a multi-socket test-system with 3 or 4 ioapics, when 4 dualcore cpus or 2 quadcore cpus installed, needs to switch to bigsmp or physflat.

Quoted 6 lines
Quoted 2 lines

CPU apic id is [4,11] instead of [0,7], and we need to check max apic id instead of cpu numbers.

for logical flat, it really shouldn't matter how large the physical apic id is. In logical flat, OS programs the LDR and the limitation is the number of cpu's which is '8'.

before i clean up 32bit, 64bit already used max_physical_apicid to check if need to switch to physflat.

for 32bit, if not switch to bigsmp, cpu with physical apic id >=8 can not be started by BSP.

YH

#10 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 19 lines · Yinghai Lu
Quoted 17 lines · Suresh Siddha

Yinghai, though not directly realted to this probe cleanup, what is this 'max_physical_apicid' doing.

I don't understand the need for this commit.

Quoted 11 lines

commit e0da33646826b66ef933d47ea2fb7a693fd849bf

Author: Yinghai Lu <[email protected]>
Date:   Sun Jun 8 18:29:22 2008 -0700

x86: introduce max_physical_apicid for bigsmp switching

a multi-socket test-system with 3 or 4 ioapics, when 4 dualcore cpus or 2 quadcore cpus installed, needs to switch to bigsmp or physflat.

CPU apic id is [4,11] instead of [0,7], and we need to check max apic id instead of cpu numbers.

Quoted 6 lines
Quoted 3 lines

for logical flat, it really shouldn't matter how large the physical apic id is. In logical flat, OS programs the LDR and the limitation is the number of cpu's which is '8'.

before i clean up 32bit, 64bit already used max_physical_apicid to check if need to switch to physflat.

No. It was introduced by your commit e0da33646826b66ef933d47ea2fb7a693fd849bf

we were using num_possible_cpus > 8 check before.

Quoted 2 lines

for 32bit, if not switch to bigsmp, cpu with physical apic id >=8 can not be started by BSP.

why?

thanks,
suresh

author
#11 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 24 lines · Suresh Siddha
Quoted 23 lines · Yinghai Lu
Quoted 20 lines · Suresh Siddha

Yinghai, though not directly realted to this probe cleanup, what is this 'max_physical_apicid' doing.

I don't understand the need for this commit.

Quoted 11 lines

commit e0da33646826b66ef933d47ea2fb7a693fd849bf

Author: Yinghai Lu <[email protected]>
Date:   Sun Jun 8 18:29:22 2008 -0700

x86: introduce max_physical_apicid for bigsmp switching

a multi-socket test-system with 3 or 4 ioapics, when 4 dualcore cpus or 2 quadcore cpus installed, needs to switch to bigsmp or physflat.

CPU apic id is [4,11] instead of [0,7], and we need to check max apic id instead of cpu numbers.

for logical flat, it really shouldn't matter how large the physical apic id is. In logical flat, OS programs the LDR and the limitation is the number of cpu's which is '8'.

Quoted 6 lines
Quoted 2 lines

before i clean up 32bit, 64bit already used max_physical_apicid to check if need to switch to physflat.

No. It was introduced by your commit e0da33646826b66ef933d47ea2fb7a693fd849bf

we were using num_possible_cpus > 8 check before.

yes. 64bit is changed to use max_phys_apicid at same patch

Quoted 5 lines
Quoted 3 lines

for 32bit, if not switch to bigsmp, cpu with physical apic id >=8 can not be started by BSP.

why?

could be apic mode is set to phys flat mode by BIOS.

get
APIC error (0x40)...

that is the reason for introducing max_phys_apicid.

#12 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit v2

Quoted 4 lines · Yinghai Lu

could be apic mode is set to phys flat mode by BIOS.

get
APIC error (0x40)...

Does this happen while sending IPI's? AP bringup should be same irrespective of the genapic mode we select here.

Quoted 1 line

that is the reason for introducing max_phys_apicid.

We may need a workaround if it is some cpu/platform specific issue. But we need to understand the actual issue and document it properly, so that it doesn't break in the future.

thanks,
suresh

author
#13 lore raw

PATCH 1/1 x86: move declaring x2apic_extra_bits

In reply to Yinghai Lu

it is for uv only

---
 arch/x86/kernel/genx2apic_phys.c |    2 --
 arch/x86/kernel/genx2apic_uv_x.c |    2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/genx2apic_phys.c +0 -2
Index: linux-2.6/arch/x86/kernel/genx2apic_phys.c
===================================================================
@@ -10,8 +10,6 @@
 #include <asm/ipi.h>
 #include <asm/genapic.h>
 
-DEFINE_PER_CPU(int, x2apic_extra_bits);
-
 static int x2apic_phys;
 
 static int set_x2apic_phys_mode(char *arg)
arch/x86/kernel/genx2apic_uv_x.c +2 -0
Index: linux-2.6/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
@@ -27,6 +27,8 @@
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/bios.h>
 
+DEFINE_PER_CPU(int, x2apic_extra_bits);
+
 static enum uv_system_type uv_system_type;
 
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
Applied
#14 lore raw

Re: [PATCH] x86: move declaring x2apic_extra_bits

Quoted 1 line · Yinghai Lu

it is for uv only

applied to tip/x86/x2apic, thanks Yinghai.

Ingo

author
#15 lore raw

PATCH 1/1 x86: add apic probe for genapic 64bit - fix

In reply to Yinghai Lu

intr_remapping_enabled get assigned later, so need to check that in setup_apic_routing

---
 arch/x86/kernel/genapic_64.c        |    6 ++++++
 arch/x86/kernel/genx2apic_cluster.c |    2 +-
 arch/x86/kernel/genx2apic_phys.c    |    2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/kernel/genapic_64.c +6 -0
Index: linux-2.6/arch/x86/kernel/genapic_64.c
===================================================================
@@ -16,6 +16,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/hardirq.h>
+#include <linux/dmar.h>
 
 #include <asm/smp.h>
 #include <asm/ipi.h>
@@ -42,6 +43,11 @@ static struct genapic *apic_probe[] __in
  */
 void __init setup_apic_routing(void)
 {
+	if (genapic == &apic_x2apic_phys || genapic == &apic_x2apic_cluster) {
+		if (!intr_remapping_enabled)
+			genapic = &apic_flat;
+	}
+
 	if (genapic == &apic_flat) {
 		if (max_physical_apicid >= 8)
 			genapic = &apic_physflat;
arch/x86/kernel/genx2apic_cluster.c +1 -1
Index: linux-2.6/arch/x86/kernel/genx2apic_cluster.c
===================================================================
@@ -14,7 +14,7 @@ DEFINE_PER_CPU(u32, x86_cpu_to_logical_a
 
 static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	if (cpu_has_x2apic && intr_remapping_enabled)
+	if (cpu_has_x2apic)
 		return 1;
 
 	return 0;
arch/x86/kernel/genx2apic_phys.c +1 -1
Index: linux-2.6/arch/x86/kernel/genx2apic_phys.c
===================================================================
@@ -21,7 +21,7 @@ early_param("x2apic_phys", set_x2apic_ph
 
 static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	if (cpu_has_x2apic && intr_remapping_enabled && x2apic_phys)
+	if (cpu_has_x2apic && x2apic_phys)
 		return 1;
 
 	return 0;
Applied
#16 lore raw

Re: [PATCH] x86: add apic probe for genapic 64bit - fix

Quoted 4 lines · Yinghai Lu

intr_remapping_enabled get assigned later, so need to check that in setup_apic_routing

applied to tip/x86/core [and merged x86/x2apic into x86/core] - thanks Yinghai.

Ingo