Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 02 Sep 2005 13:58:55 -0400
From:      Ben Thomas <bthomas@virtualiron.com>
To:        freeBSD-gnats-submit@FreeBSD.org
Subject:   i386/85654: [patch] separate max cpu from max apic in i386 code
Message-ID:  <431892DF.4090705@virtualiron.com>
Resent-Message-ID: <200509021800.j82I0avm055250@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         85654
>Category:       i386
>Synopsis:       [patch] separate max cpu from max apic in i386 code
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 02 18:00:36 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Ben Thomas
>Release:        FreeBSD 5.4-RELEASE i386
>Organization:
Virtual Iron Software
>Environment:
System: FreeBSD bthomas4.katana-technology.com 5.4-RELEASE FreeBSD 5.4-RELEASE #10: Sun Aug 28 13:48:00 EDT 2005 ben@bthomas4.katana-technology.com:/usr/obj/usr/home/ben/BSD/RELENG_5_4_0_RELEASE/src/sys/BEN i386


>Description:

This change separates the logical CPU id from the APIC id when bringing
up a system.  This was inspired by a 4-CPU, hyperthreaded system which
had APIC ids up to 32.  The logical CPU range would be 0 through 7, but
the system wouldn't bring them online as the APIC range exceeded the
defined CPU range of 0 through 16.  Separating the logical CPU max from
the APIC max fixes this problem, and also allows any table configured
for CPU max to only need to be as big as the number of logical CPUs and
not the largest APIC value.

This patch is against the 5_4_0_RELEASE code


>How-To-Repeat:
>Fix:

--- mp_machdep.c-DIFF begins here ---
--- /usr/src.original/sys/i386/i386/mp_machdep.c	Sun May  1 01:38:13 2005
+++ /usr/src/sys/i386/i386/mp_machdep.c	Fri Aug 12 09:53:08 2005
@@ -198,12 +198,13 @@
  * Store data from cpu_add() until later in the boot when we actually setup
  * the APs.
  */
-struct cpu_info {
+struct cpu_info {			/* Indexed by APIC id */
 	int	cpu_present:1;
 	int	cpu_bsp:1;
 	int	cpu_disabled:1;
-} static cpu_info[MAXCPU];
-static int cpu_apic_ids[MAXCPU];
+} __attribute__((packed)) static cpu_info[MAXAPIC];
+
+static int cpu_apic_ids[MAXCPU];	/* Indexed by logical CPU id */
 
 /* Holds pending bitmap based IPIs per CPU */
 static volatile u_int cpu_ipi_pending[MAXCPU];
@@ -244,7 +245,7 @@
 		return;
 	group = &mp_groups[0];
 	groups = 1;
-	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
+	for (cpu = 0, apic_id = 0; apic_id < MAXAPIC; apic_id++) {
 		if (!cpu_info[apic_id].cpu_present)
 			continue;
 		/*
@@ -285,9 +286,9 @@
 cpu_add(u_int apic_id, char boot_cpu)
 {
 
-	if (apic_id >= MAXCPU) {
-		printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n",
-		    apic_id, MAXCPU - 1);
+	if (apic_id >= MAXAPIC) {
+		printf("SMP: CPU APIC id %d exceeds maximum CPU APIC %d, ignoring\n",
+		    apic_id, MAXAPIC - 1);
 		return;
 	}
 	KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
@@ -420,7 +421,7 @@
 
 	/* List CPUs */
 	printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
-	for (i = 1, x = 0; x < MAXCPU; x++) {
+	for (i = 1, x = 0; x < MAXAPIC; x++) {
 		if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp)
 			continue;
 		if (cpu_info[x].cpu_disabled)
@@ -587,7 +588,7 @@
 	/* Force us to allocate cluster 0 at the start. */
 	cluster = -1;
 	cluster_id = APIC_MAX_INTRACLUSTER_ID;
-	for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
+	for (apic_id = 0; apic_id < MAXAPIC; apic_id++) {
 		if (!cpu_info[apic_id].cpu_present)
 			continue;
 		if (cluster_id == APIC_MAX_INTRACLUSTER_ID) {
@@ -640,7 +641,7 @@
 	invltlb();
 
 	/* start each AP */
-	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
+	for (cpu = 0, apic_id = 0; apic_id < MAXAPIC; apic_id++) {
 
 		/* Ignore non-existent CPUs and the BSP. */
 		if (!cpu_info[apic_id].cpu_present ||
@@ -655,6 +656,12 @@
 		}
 
 		cpu++;
+
+		if (cpu >= MAXCPU) {
+			printf("SMP: CPU %d (APIC ID %d) exceeds maximum CPU %d, ignoring\n",
+		   	 cpu, apic_id, MAXCPU-1);
+			break;
+		}
 
 		/* save APIC ID for this logical ID */
 		cpu_apic_ids[cpu] = apic_id;
--- mp_machdep.c-DIFF ends here ---

--- param.h-DIFF begins here ---
--- /usr/src.original/sys/i386/include/param.h	Fri Feb  4 20:01:53 2005
+++ /usr/src/sys/i386/include/param.h	Fri Aug 12 09:50:39 2005
@@ -75,6 +75,8 @@
 #define MAXCPU		1
 #endif /* SMP */
 
+#define MAXAPIC		32
+
 #define ALIGNBYTES	_ALIGNBYTES
 #define ALIGN(p)	_ALIGN(p)
 
--- param.h-DIFF ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?431892DF.4090705>