On Sat, Apr 11, 2020 at 09:46:49PM +0200, Patrick Wildt wrote:
> > OpenBSD 6.7-beta (GENERIC.MP) #552: Fri Apr 10 20:48:05 MDT 2020
> > [email protected]:/usr/src/sys/arch/arm64/compile/GENERIC.MP
> >
> > panic: _dmamap_sync: ran off map!
>
> Oh, wow! That means that the DMA sync is using a longer length than the
> DMA buffer has segments for. It's very plausible that this happens on
> the Pinebook, and not on an x86 machine, because on the Pinebook it has
> to do DMA syncs, while on x86 that's essentially a no-op.
>
> > Stopped at panic+0x150:
> > TID PID UID PRFLAGS PFLAGS CPU COMMAND
> > 242142 87433 0 0x100002 0 3 sha256
> > 192114 36379 0 0x14000 0x200 2K sdmmc2
> > db_enter() at panic+0x14c
> > panic() at ehci_idone+0x1d4
> > ehci_idone() at ehci_softintr+0x158
>
> I see! This is the one. I think I made a slight error in this
> function, since for all the other drivers I made sure to sync only
> on successful completions, while for ehci(4) I missed this for one.
>
> I think this diff should fix it, can you give it a go?
Unfortunately kernel panics in very similar way:
ddb{0}> show panic
_dmamap_sync: ran off map!
ddb{0}> trace
db_enter() at panic+0x14c
panic() at ehci_idone+0x1d8
ehci_idone() at ehci_softintr+0x158
ehci_softintr() at softintr_biglock_wrap+0x1c
softintr_biglock_wrap() at softintr_dispatch+0x9c
softintr_dispatch() at arm_do_pending_intr+0xa8
arm_do_pending_intr() at ampintc_irq_handle+0x178
ampintc_irq_handle() at arm_cpu_intr+0x30
arm_cpu_intr() at handle_el1h_irq+06c
handle_el1h_irq() at sched_idle+0x220
sched_idle() at proc_trampoline+0x10
> mpi@, kettenis@: ok?
>
> Patrick
>
> diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
> index 41851defe4f..249bb073fca 100644
> --- a/sys/dev/usb/ehci.c
> +++ b/sys/dev/usb/ehci.c
> @@ -912,13 +912,14 @@ ehci_idone(struct usbd_xfer *xfer)
> xfer->status = USBD_STALLED;
> else
> xfer->status = USBD_IOERROR; /* more info XXX */
> - } else
> + } else {
> + if (xfer->actlen)
> + usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
> + usbd_xfer_isread(xfer) ?
> + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
> xfer->status = USBD_NORMAL_COMPLETION;
> + }
>
> - if (xfer->actlen)
> - usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
> - usbd_xfer_isread(xfer) ?
> - BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
> usb_transfer_complete(xfer);
> DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
> }
--
Regards,
Mikolaj