Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Nov 2004 13:49:01 -0500
From:      John Baldwin <jhb@FreeBSD.org>
To:        alpha@FreeBSD.org
Subject:   Patch to tweak FreeBSD CPU IDs in the SMP support
Message-ID:  <200411031349.01668.jhb@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
I would appreciate it if folks with SMP machines could please test the patch 
below.  It should ensure among other things that the boot processor will now 
always have a FreeBSD cpu ID of 0 and that the FreeBSD cpu IDs will now be 
allocate independent of the PAL IDs from the HWPRB.  I'm especially 
interested in reports from machines where the PAL IDs don't match the CPU 
IDs.  (My one SMP alpha box always seems to boot from CPU 0 and so the IDs 
match up so I can't tell if I've accidentally gotten an id variable backwards 
somewhere.)

--- //depot/vendor/freebsd/src/sys/alpha/alpha/machdep.c	2004/09/05 02:10:52
+++ //depot/projects/smpng/sys/alpha/alpha/machdep.c	2004/10/27 17:45:12
@@ -864,7 +864,8 @@
 		/* This is not a 'struct user' */
 		size_t sz = round_page(KSTACK_PAGES * PAGE_SIZE);
 		pcpup = (struct pcpu *) pmap_steal_memory(sz);
-		pcpu_init(pcpup, alpha_pal_whami(), sz);
+		pcpu_init(pcpup, 0, sz);
+		pcpup->pc_pal_id = alpha_pal_whami();
 		alpha_pal_wrval((u_int64_t) pcpup);
 		PCPU_GET(next_asn) = 1;	/* 0 used for proc0 pmap */
 		PCPU_SET(curthread, &thread0);
--- //depot/vendor/freebsd/src/sys/alpha/alpha/mp_machdep.c	2004/01/07 
23:00:44
+++ //depot/projects/smpng/sys/alpha/alpha/mp_machdep.c	2004/11/02 22:27:44
@@ -61,23 +61,23 @@
 
 static struct mtx ap_boot_mtx;
 
-u_int boot_cpu_id;
+u_int64_t boot_cpu_id;
 
 static void	release_aps(void *dummy);
 static int	smp_cpu_enabled(struct pcs *pcsp);
 extern void	smp_init_secondary_glue(void);
-static int	smp_send_secondary_command(const char *command, int cpuid);
-static int	smp_start_secondary(int cpuid);
+static int	smp_send_secondary_command(const char *command, int pal_id);
+static int	smp_start_secondary(int pal_id, int cpuid);
 
 /*
  * Communicate with a console running on a secondary processor.
  * Return 1 on failure.
  */
 static int
-smp_send_secondary_command(const char *command, int cpuid)
+smp_send_secondary_command(const char *command, int pal_id)
 {
-	u_int64_t mask = 1L << cpuid;
-	struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid);
+	u_int64_t mask = 1L << pal_id;
+	struct pcs *cpu = LOCATE_PCS(hwrpb, pal_id);
 	int i, len;
 
 	/*
@@ -165,7 +165,7 @@
 	/*
 	 * Set flags in our per-CPU slot in the HWRPB.
 	 */
-	cpu = LOCATE_PCS(hwrpb, PCPU_GET(cpuid));
+	cpu = LOCATE_PCS(hwrpb, PCPU_GET(pal_id));
 	cpu->pcs_flags &= ~PCS_BIP;
 	cpu->pcs_flags |= PCS_RC;
 	alpha_mb();
@@ -216,9 +216,9 @@
 }
 
 static int
-smp_start_secondary(int cpuid)
+smp_start_secondary(int pal_id, int cpuid)
 {
-	struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid);
+	struct pcs *cpu = LOCATE_PCS(hwrpb, pal_id);
 	struct pcs *bootcpu = LOCATE_PCS(hwrpb, boot_cpu_id);
 	struct alpha_pcb *pcb = (struct alpha_pcb *) cpu->pcs_hwpcb;
 	struct pcpu *pcpu;
@@ -226,12 +226,12 @@
 	size_t sz;
 
 	if ((cpu->pcs_flags & PCS_PV) == 0) {
-		printf("smp_start_secondary: cpu %d PALcode invalid\n", cpuid);
+		printf("smp_start_secondary: cpu %d PALcode invalid\n", pal_id);
 		return 0;
 	}
 
 	if (bootverbose)
-		printf("smp_start_secondary: starting cpu %d\n", cpuid);
+		printf("smp_start_secondary: starting cpu %d\n", pal_id);
 
 	sz = round_page((UAREA_PAGES + KSTACK_PAGES) * PAGE_SIZE);
 	pcpu = malloc(sz, M_TEMP, M_NOWAIT);
@@ -241,6 +241,7 @@
 	}
 	
 	pcpu_init(pcpu, cpuid, sz);
+	pcpu->pc_pal_id = pal_id;
 
 	/*
 	 * Copy the idle pcb and setup the address to start executing.
@@ -270,7 +271,7 @@
 	/*
 	 * Fire it up and hope for the best.
 	 */
-	if (!smp_send_secondary_command("START\r\n", cpuid)) {
+	if (!smp_send_secondary_command("START\r\n", pal_id)) {
 		printf("smp_start_secondary: can't send START command\n");
 		pcpu_destroy(pcpu);
 		free(pcpu, M_TEMP);
@@ -296,7 +297,7 @@
 	 * It worked (I think).
 	 */
 	if (bootverbose)
-		printf("smp_start_secondary: cpu %d started\n", cpuid);
+		printf("smp_start_secondary: cpu %d started\n", pal_id);
 	return 1;
 }
 
@@ -329,16 +330,18 @@
 void
 cpu_mp_setmaxid(void)
 {
-	int i;
+	u_int64_t i;
 
 	mp_maxid = 0;
-	for (i = 0; i < hwrpb->rpb_pcs_cnt && i < MAXCPU; i++) {
-		if (i == PCPU_GET(cpuid))
+	for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
+		if (i == PCPU_GET(pal_id))
 			continue;
 		if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i)))
 			continue;
-		mp_maxid = i;
+		mp_maxid++;
 	}
+	if (mp_maxid > MAXCPU)
+		mp_maxid = MAXCPU;
 }
 
 int
@@ -348,7 +351,7 @@
 
 	/* XXX: Need to check for valid platforms here. */
 
-	boot_cpu_id = PCPU_GET(cpuid);
+	boot_cpu_id = PCPU_GET(pal_id);
 	KASSERT(boot_cpu_id == hwrpb->rpb_primary_cpu_id,
 	    ("cpu_mp_probe() called on non-primary CPU"));
 	all_cpus = PCPU_GET(cpumask);
@@ -358,12 +361,10 @@
 	/* Make sure we have at least one secondary CPU. */
 	cpus = 0;
 	for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
-		if (i == PCPU_GET(cpuid))
+		if (i == PCPU_GET(pal_id))
 			continue;
 		if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i)))
 			continue;
-		if (i > MAXCPU)
-			continue;
 		cpus++;
 	}
 	return (cpus);
@@ -372,10 +373,11 @@
 void
 cpu_mp_start(void)
 {
-	int i;
+	int i, cpuid;
 
 	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
 
+	cpuid = 1;
 	for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
 		struct pcs *pcsp;
 
@@ -410,22 +412,30 @@
 			printf("CPU %d disabled by loader.\n", i);
 			continue;
 		}
-		all_cpus |= (1 << i);
-		mp_ncpus++;
+		if (smp_start_secondary(i, cpuid)) {
+			all_cpus |= (1 << cpuid);
+			mp_ncpus++;
+			cpuid++;
+		}
 	}
 	PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
-
-	for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
-		if (i == boot_cpu_id)
-			continue;
-		if (!CPU_ABSENT(i))
-			smp_start_secondary(i);
-	}
 }
 
 void
 cpu_mp_announce(void)
 {
+	struct pcpu *pc;
+	int i;
+	
+	/* List CPUs */
+	printf(" cpu0 (BSP): PAL ID: %2lu\n", boot_cpu_id);
+	for (i = 1; i < MAXCPU; i++) {
+		if (CPU_ABSENT(i))
+			continue;
+		pc = pcpu_find(i);
+		MPASS(pc != NULL);
+		printf(" cpu%d (AP): PAL ID: %2lu\n", i, pc->pc_pal_id);
+	}
 }
 
 /*
@@ -446,8 +456,9 @@
 		if (pcpu) {
 			atomic_set_64(&pcpu->pc_pending_ipis, ipi);
 			alpha_mb();
-			CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)", cpuid);
-			alpha_pal_wripir(cpuid);
+			CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)",
+			    pcpu->pc_pal_id);
+			alpha_pal_wripir(pcpu->pc_pal_id);
 		}
 	}
 }
@@ -529,8 +540,8 @@
 	 * requests to provide PALcode to secondaries and to start up new
 	 * secondaries that are added to the system on the fly.
 	 */
-	if (PCPU_GET(cpuid) == boot_cpu_id) {
-		u_int cpuid;
+	if (PCPU_GET(pal_id) == boot_cpu_id) {
+		u_int pal_id;
 		u_int64_t txrdy;
 #ifdef DIAGNOSTIC
 		struct pcs *cpu;
@@ -539,18 +550,18 @@
 
 		alpha_mb();
 		while (hwrpb->rpb_txrdy != 0) {
-			cpuid = ffs(hwrpb->rpb_txrdy) - 1;
+			pal_id = ffs(hwrpb->rpb_txrdy) - 1;
 #ifdef DIAGNOSTIC
-			cpu = LOCATE_PCS(hwrpb, cpuid);
+			cpu = LOCATE_PCS(hwrpb, pal_id);
 			bcopy(&cpu->pcs_buffer.txbuf, buf,
 			    cpu->pcs_buffer.txlen);
 			buf[cpu->pcs_buffer.txlen] = '\0';
-			printf("SMP From CPU%d: %s\n", cpuid, buf);
+			printf("SMP From CPU%d: %s\n", pal_id, buf);
 #endif
 			do {
 				txrdy = hwrpb->rpb_txrdy;
 			} while (atomic_cmpset_64(&hwrpb->rpb_txrdy, txrdy,
-			    txrdy & ~(1 << cpuid)) == 0);
+			    txrdy & ~(1 << pal_id)) == 0);
 		}
 	}
 }
--- //depot/vendor/freebsd/src/sys/alpha/include/pcpu.h	2001/12/11 23:42:08
+++ //depot/projects/smpng/sys/alpha/include/pcpu.h	2004/10/27 17:45:12
@@ -34,6 +34,7 @@
 
 #define	PCPU_MD_FIELDS							\
 	struct alpha_pcb pc_idlepcb;		/* pcb for idling */	\
+	u_int64_t	pc_pal_id;		/* physical CPU ID */	\
 	u_int64_t	pc_idlepcbphys;		/* pa of pc_idlepcb */	\
 	u_int64_t	pc_pending_ipis;	/* pending IPI's */	\
 	u_int32_t	pc_next_asn;		/* next ASN to alloc */	\
--- //depot/vendor/freebsd/src/sys/alpha/include/smp.h	2001/08/13 23:42:17
+++ //depot/projects/smpng/sys/alpha/include/smp.h	2004/10/29 21:11:53
@@ -26,7 +26,7 @@
 
 #ifndef LOCORE
 
-extern u_int			boot_cpu_id;
+extern u_int64_t		boot_cpu_id;
 
 void	ipi_selected(u_int cpus, u_int64_t ipi);
 void	ipi_all(u_int64_t ipi);

-- 
John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org



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