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

Reply via email to