PERFORCE change 95415 for review

Kip Macy kmacy at FreeBSD.org
Mon Apr 17 04:53:01 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=95415

Change 95415 by kmacy at kmacy_storage:sun4v_rwbuf on 2006/04/17 04:51:57

	add work arounds for various IPI related issues
	add ackmask for pmap functions to use for acknowledgement

Affected files ...

.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/mp_machdep.c#4 edit

Differences ...

==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/mp_machdep.c#4 (text+ko) ====

@@ -29,6 +29,7 @@
  */
 /*-
  * Copyright (c) 2002 Jake Burkholder.
+ * Copyright (c) 2006 Kip Macy <kmacy at FreeBSD.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -275,7 +276,6 @@
 	u_int clock;
 	int cpuid, bp_skipped;
 	u_long s;
-	mtx_init(&ipi_mtx, "ipi", NULL, MTX_SPIN);
 
 	root = OF_peer(0);
 	csa = &cpu_start_args;
@@ -301,7 +301,6 @@
 		while (csa->csa_state != CPU_INIT)
 			;
 		intr_restore(s);
-
 		mp_ncpus = cpuid + 1;
 #if 0
 		cpu_identify(0, clock, cpuid);
@@ -317,7 +316,12 @@
 		pc->pc_node = child;
 
 		all_cpus |= 1 << cpuid;
+#if 1
 		if (mp_ncpus == MAXCPU)
+#else 
+		if (mp_ncpus == 16)
+#endif
+
 			break;
 	}
 	PCPU_SET(other_cpus, all_cpus & ~(1 << PCPU_GET(cpuid)));
@@ -377,26 +381,22 @@
 	trap_init();
 	cpu_intrq_init();
 	tick_start();
+	/* 
+	 * enable interrupts now that we have our trap table set
+	 */
+	intr_restore_all(PSTATE_KERNEL);
 
 	smp_cpus++;
 	KASSERT(curthread != NULL, ("cpu_mp_bootstrap: curthread"));
 	PCPU_SET(other_cpus, all_cpus & ~(1 << PCPU_GET(cpuid)));
 	printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
-
 	csa->csa_count--;
 	membar(StoreLoad);
 	csa->csa_state = CPU_BOOTSTRAP;
+
 	while (csa->csa_count != 0)
 		;
-#ifdef SIMULATOR
-	DELAY(300*PCPU_GET(cpuid));
-#else
-	DELAY(300000*PCPU_GET(cpuid));
-#endif
 	/* ok, now grab sched_lock and enter the scheduler */
-#if 0
-	printf("entering scheduler\n");
-#endif
 	mtx_lock_spin(&sched_lock);
 	spinlock_exit();
 	PCPU_SET(switchtime, cpu_ticks());
@@ -450,29 +450,20 @@
 }
 
 void
-cpu_ipi_selected(u_int icpus, u_long d0, u_long d1, u_long d2)
+cpu_ipi_selected(int cpu_count, uint16_t *cpulist, u_long d0, u_long d1, u_long d2, uint64_t *ackmask)
 {
 
-	int i, cpu_count, retries;
-	uint16_t *cpulist;
-	u_int cpus;
+	int i, retries;
 
-	cpulist = PCPU_GET(cpulist);
-	init_mondo(d0, d1, d2);
+	init_mondo(d0, d1, d2, (uint64_t)ackmask);
 
-	for (cpu_count = 0, i = 0, cpus = icpus & ~PCPU_GET(cpumask); i < 32 && cpus; 
-	     cpus = cpus >> 1, i++) {
-		if (!(cpus & 0x1))
-			continue;
+	retries = 0;
 
-		cpulist[cpu_count] = (uint16_t)i;
-		cpu_count++;
-	}
-	retries = 0;
 retry:
 	if (cpu_count) {
 		int error, new_cpu_count;
 		vm_paddr_t cpulist_ra;
+
 		cpulist_ra = TLB_DIRECT_TO_PHYS((vm_offset_t)cpulist);
 		if ((error = hv_cpu_mondo_send(cpu_count, cpulist_ra)) == H_EWOULDBLOCK) {
 			new_cpu_count = 0;
@@ -486,11 +477,25 @@
 				printf("no more cpus to send to but mondo_send returned EWOULDBLOCK\n");
 				return;
 			}
-			if (retries < 5000)
+			if ((retries & 0x1) == 0x1)
+				DELAY(10);
+
+			if (retries < 50000)
 				goto retry;
+			else {
+				printf("used up retries - cpus remaining: %d  - cpus: ",
+				       cpu_count);
+				for (i = 0; i < cpu_count; i++)
+					printf("#%d ", cpulist[i]);
+				printf("\n");
+			}
 		}
-		if (error == H_ENOCPU)
-			printf("cpuid==%d not considered valid - cpus=0x%x\n", cpulist[0], icpus);
+		if (error == H_ENOCPU) {
+			printf("bad cpuid: ");
+			for (i = 0; i < cpu_count; i++)
+				printf("#%d ", cpulist[i]);
+			printf("\n");
+		}		
 		if (error)
 			panic("can't handle error %d from cpu_mondo_send\n", error);
 	}
@@ -499,13 +504,40 @@
 
 
 void
-ipi_selected(u_int cpus, u_int ipi)
+ipi_selected(u_int icpus, u_int ipi)
 {
-	cpu_ipi_selected(cpus, (u_long)tl_ipi_level, ipi, 0);
+	int i, cpu_count;
+	uint16_t *cpulist;
+	cpumask_t cpus;
+	uint64_t ackmask;
+
+	/* 1) our cpu_ipi_ast doesn't do anything
+	 * 2) a reschedule will be triggered at the next timer interrupt
+	 * 3) forward_wakeup appears to abuse ASTs
+	 * 4) handling 4-way threading vs 2-way threading will just serve
+	 *    to further obfuscate forward_wakeup
+	 */
+	if (ipi == IPI_AST)
+		return;
+	
+
+	cpulist = PCPU_GET(cpulist);
+	cpus = ((icpus & ~PCPU_GET(cpumask)) & ipi_ready_mask);
+	
+	for (cpu_count = 0, i = 0; i < 32 && cpus; cpus = cpus >> 1, i++) {
+		if (!(cpus & 0x1))
+			continue;
+		
+		cpulist[cpu_count] = (uint16_t)i;
+		cpu_count++;
+	}
+	
+	cpu_ipi_selected(cpu_count, cpulist, (u_long)tl_ipi_level, ipi, 0, &ackmask);
+	
 }
 
 void
 ipi_all_but_self(u_int ipi)
 {
-	cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi);
+	ipi_selected(PCPU_GET(other_cpus), ipi);
 }


More information about the p4-projects mailing list