On Sat, Apr 11, 2020 at 12:41:36PM +0000, Mikolaj Kucharski wrote:
> On Sat, Apr 11, 2020 at 09:06:57AM +0000, Mikolaj Kucharski wrote:
> > >Synopsis:  kernel panic with message _dmamap_sync: ran off map!
> > >Category:  kernel
> > >Environment:
> >     System      : OpenBSD 6.7
> >     Details     : OpenBSD 6.7-beta (GENERIC.MP) #546: Mon Apr  6 12:39:22 
> > MDT 2020
> >                      
> > [email protected]:/usr/src/sys/arch/arm64/compile/GENERIC.MP
> > 
> >     Architecture: OpenBSD.arm64
> >     Machine     : arm64
> > >Description:
> >     Kernel panic. It happens after usage of network via wireless adapter
> > connected via USB, urtwn(4):
> > 
> > urtwn0 at uhub4 port 2 configuration 1 interface 0 "Realtek 802.11n WLAN 
> > Adapter" rev 2.00/2.00 addr 5
> > urtwn0: MAC/BB RTL8188CUS, RF 6052 1T1R, address 80:1f:02:4b:6a:6b
> > 
> > Currently don't have trace output from ddb as it doesn't have function 
> > names, but addresses.
> > Will try to update kernel to latest arm64 snapshot.
> > 
> > >How-To-Repeat:
> >     Connect urtwn(4) to Pinebook and use network, after a while kernel 
> > panics.
> > For me simplest way is to start `sysupgrade -s -f`
> > 
> > >Fix:
> >     Unknown.
> 
> 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?

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));
 }

Reply via email to