NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-evbarm/54696: Kernel panic in bus_dma.c on Raspberry Pi 3B/3B+



The following reply was made to PR port-evbarm/54696; it has been noted by GNATS.

From: sc.dying%gmail.com@localhost
To: Tetsuya Isaki <isaki%pastel-flower.jp@localhost>, gnats-bugs%netbsd.org@localhost
Cc: port-evbarm-maintainer%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
 netbsd-bugs%netbsd.org@localhost, dhop%nwlink.com@localhost
Subject: Re: port-evbarm/54696: Kernel panic in bus_dma.c on Raspberry Pi
 3B/3B+
Date: Thu, 14 Nov 2019 22:29:55 +0000

 On 2019/11/14 08:39, Tetsuya Isaki wrote:
 > At Wed, 13 Nov 2019 21:05:01 +0000 (UTC),
 > Michael van Elst wrote:
 >>  >[   153.534940] panic: kernel diagnostic assertion "len > 0 && offset + len <= map->dm_mapsize" failed: file "/usr/src/sys/arch/arm/arm32/bus_dma.c", line 1058 len 0 offset 0 mapsize 8192
 >>  
 >>  A zero length transfer. In that case it would be a uaudio (or audio?) bug.
 >>  
 >>  No idea why that should be aarch64-specific.
 > 
 > I think it's dwc2's issue.
 
 Seconded.
 
 > 
 > According to report, calling usb_syncmem() with len == 0 in
 > dwc2_device_start() caused a panic.
 > 
 >  sys/external/bsd/dwc2/dwc2.c:
 >   929 dwc2_device_start(struct usbd_xfer *xfer)
 >   930 {
 >   :
 >   966     if (xfertype == UE_CONTROL) {
 >   :
 >   990     } else {
 >   :
 >   995         len = xfer->ux_length;
 >   996     }
 >   :
 >  1027     if (!(xfertype == UE_CONTROL && len == 0)) {
 >  1028         dwc2_urb->usbdma = &xfer->ux_dmabuf;
 >  1029         dwc2_urb->buf = KERNADDR(dwc2_urb->usbdma, 0);
 >  1030         dwc2_urb->dma = DMAADDR(dwc2_urb->usbdma, 0);
 >  1031
 >  1032         usb_syncmem(&xfer->ux_dmabuf, 0, len,
 >  1033             dir == UE_DIR_IN ?
 >  1034             BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 
 > 
 > Here len passed to usb_syncmem() is xfer->ux_length.
 > 
 > According to reported backtrace,
 > - dwc2_device_start(xfer) is called from dwc2_device_isoc_transfer(xfer).
 > - dwc2_device_isoc_transfer(xfer) is called from usbd_transfer(xfer) as
 >   up_methods->upm_transfer.
 > - usbd_transfer(xfer) seems be called from uaudio_chan_rtransfer(ch)
 >   and uaudio_chan_rtransfer(ch) seems be inline-expanded in
 >   uaudio_trigger_input().
 > 
 >  sys/dev/usb/uaudio.c:
 >  2838 uaudio_chan_rtransfer(struct chan *ch)
 >  2839 {
 >  :
 >  2874     usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0,
 >  2875         uaudio_chan_rintr);
 >  2876
 >  2877     (void)usbd_transfer(cb->xfer);
 >  2878 }
 > 
 > usbd_setup_isoc_xfer() initializes ux_length == 0.
 > 
 >   592 usbd_setup_isoc_xfer(struct usbd_xfer *xfer, void *priv, uint16_t
 >       *frlengths,
 >   593     uint32_t nframes, uint16_t flags, usbd_callback callback)
 >   594 {
 >   595     xfer->ux_priv = priv;
 >   596     xfer->ux_buffer = NULL;
 >   597     xfer->ux_length = 0;
 >  
 > And then see also similar (the same?) PR port-arm/54615,
 > sc.dying%gmail.com@localhost wrote:
 >>  At line 1032 of sys/external/bsd/dwc2/dwc2.c usb_syncmem is called.
 >>
 >>> 		usb_syncmem(&xfer->ux_dmabuf, 0, len,
 >>> 		    dir == UE_DIR_IN ?
 >>> 			BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 >>
 >> len = xfer->ux_length, however, ux_length is always 0 for isoc transfers.
 > 
 > I just read source code and I have no environment.  But if my
 > understanding is correct, I think that dwc2_device_start() needs
 > to handle length == 0 properly.
 
 This bug can be solved by wrapping above usb_syncmem with if (len != 0) {}
 or by changing arm/arm32/bus_dma.c accept zero length sync like x86 does.
 
 But the transfer length of isoc xfer is sum of xfer->ux_frlengths[i]
 where i = 0.. xfer->ux_nframes - 1, not zero.
 dwc2 should do this usb_syncmem if xfertype == UE_{INTERRUPT,BULK},
 UE_CONTROL that has data phase (that is, len != 0), or if xfertype ==
 UE_ISOCHRONOUS, should do usb_syncmem for each chunk of ux_frlengths.
 
 However, the uaudio works with dwc2 even if avobe usb_syncmem is ignored.
 I think dwc2 does usb_syncmem for isoc data buf somewhere else, but
 I'm not sure where it is.
 
 > 
 > Thanks,
 > ---
 > Tetsuya Isaki <isaki%pastel-flower.jp@localhost / isaki%NetBSD.org@localhost>
 > 
 


Home | Main Index | Thread Index | Old Index