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