DDB and SMP causes Unaligned Reference
Alan Robinson
alan.robinson at fujitsu-siemens.com
Fri Jun 6 09:31:36 PDT 2003
Using the manual escape to debugger with an SMP kernel
causes an unaligned reference while stopping the other
CPU, the system then hangs.
#
# CPU1 stopping CPUs: 0x00000001...
# fatal kernel trap (cpu 0):
#
# trap vector = 0x1e (Unaligned Reference)
# cr.iip = 0xe0000000009a1320
# cr.ipsr = 0x1210080a6010 (mfl,ic,i,dt,dfh,rt,cpl=0,it,ri=1,bn)
# cr.isr = 0x20200000000 (code=0,vector=0,w,ei=1)
# cr.ifa = 0xe000000000004228
# curthread = 0xe00000003d9bb080
# pid = 12, comm = idle: cpu0
# CPU0 stopping CPUs: 0x00000002...
#
(The self built kernel was built using projects/ia64 cvsup'd sources
which are now a day or two old)
The cr.iip points into swapctx (or savectx) which was called from
from interrupt() as follows....
} else if (vector == ipi_vector[IPI_STOP]) {
u_int32_t mybit = PCPU_GET(cpumask);
CTR1(KTR_SMP, "IPI_STOP, cpuid=%d", PCPU_GET(cpuid));
savectx(PCPU_GET(pcb));
stopped_cpus |= mybit;
while ((started_cpus & mybit) == 0)
/* spin */;
started_cpus &= ~mybit;
stopped_cpus &= ~mybit;
if (PCPU_GET(cpuid) == 0 && cpustop_restartfunc != NULL) {
void (*f)(void) = cpustop_restartfunc;
cpustop_restartfunc = NULL;
(*f)();
}
I cannot find a place where PCU_SET(pcb) is used nor can I find a
direct setting of pc_pcb :-(
The following 2 line change in sys/ia64/ia64/mp_machdep.c fixes the problem
for me.
+static struct pcb ia64_intr_pcb[MAXCPU];
void
cpu_mp_start()
{
struct pcpu *pc;
ap_spin = 1;
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
pc->pc_current_pmap = kernel_pmap;
pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask;
+ pc->pc_pcb = &(ia64_intr_pcb[pc->pc_cpuid]);
if (pc->pc_cpuid > 0) {
ap_stack = malloc(KSTACK_PAGES * PAGE_SIZE, M_PMAP,
M_WAITOK);
ap_pcpu = pc;
ap_delay = 2000;
ap_awake = 0;
I can now get the following:
# manual escape to debugger
# CPU1 stopping CPUs: 0x00000001... stopped.
# Stopped at Debugger+0x31: nop.m 0x0
# db> trace
# Debugger(0xe000000000a10a78, 0xe000000000990bf0, 0x692) at Debugger+0x30
# scgetc(0xe0000000002ae800, 0x2, 0xe0000000011f2cb0) at scgetc+0xbe0
# sckbdevent(0xe000000000b232e8, 0x0, 0xe0000000002ae800) at sckbdevent+0x640
# ukbd_interrupt(0xe000000000b232e8, 0x0) at ukbd_interrupt+0x850
# ukbd_intr(0xe000000001167a00, 0xe000000000b232e8, 0x0) at ukbd_intr+0x80
# usb_transfer_complete(0xe000000001167a00, 0xe000000000ae6110) at usb_transfer_complete+0x400
# ohci_softintr(0xe0000000010ab000) at ohci_softintr+0x240
# usb_schedsoftintr(0xe0000000010ab000, 0xe000000000ae6110, 0xe0000000006728f0, 0x30a) at usb_schedsoftintr+0x50
# ohci_intr1(0xe0000000010ab000) at ohci_intr1+0x440
# ohci_intr(0xe0000000010ab000, 0xe0000000006f97b0, 0x1024) at ohci_intr+0x80
# ithread_loop(0xe0000000011a8200, 0xe000000001118100, 0xe000000000ae6110, 0xe000000000ab5590) at ithread_loop+0x460
# fork_exit(0xe000000000a1d4d8, 0xe0000000011a8200, 0xa000000000019580) at fork_exit+0x1b0
# enter_userland() at enter_userland
# db> c
# CPU1 restarting CPUs: 0x00000001... restarted.
# manual escape to debugger
# CPU0 stopping CPUs: 0x00000002... stopped.
# Stopped at Debugger+0x31: nop.m 0x0
# db> c
# CPU0 restarting CPUs: 0x00000002... restarted.
#
is the double continue normal ?
Alan
More information about the freebsd-ia64
mailing list