Date: Fri, 7 Nov 2008 18:11:26 +0100 From: Hans Petter Selasky <hselasky@c2i.net> To: freebsd-current@freebsd.org Cc: Jeremy Chadwick <koitsu@freebsd.org> Subject: Re: Kernel panic when copying data to umass device (USB4BSD) - problem found Message-ID: <200811071811.27181.hselasky@c2i.net> In-Reply-To: <20081107082740.GA1334@icarus.home.lan> References: <20081107082740.GA1334@icarus.home.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 07 November 2008, Jeremy Chadwick wrote: > Not sure if this is caused by problems with USB4BSD or not, as I can > reproduce it on RELENG_7 (but there, the kernel does not panic; it just > "wedges" in a loop/thread somewhere; SSH sessions remain up, but > commands running stop; hitting Ctrl-T shows them in all sorts of > different states, but the states never change; hitting Ctrl-Alt-Esc does > in fact drop me to db>). > Hi Jeremy, I've reproduced the issue with some mods to the usb2_busdma.c on 32-bit arcitecture and have made a fix for this problem. Try the following patch and re-test! Some mem-stick benchmarks would be nice ... My private SVN also has this patch in addition to P4. --HPS http://perforce.freebsd.org/chv.cgi?CH=152624 Fix some problems related to busdma: Need to unload DMA maps before re-use! Fix a corner case when loading zero bytes. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#10 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#10 (text+ko) ==== @@ -597,6 +597,12 @@ uptag = pc->tag_parent; /* + * We have to unload the previous loaded DMA + * pages before trying to load a new one! + */ + bus_dmamap_unload(pc->tag, pc->map); + + /* * Try to load memory into DMA. */ err = bus_dmamap_load( @@ -612,6 +618,12 @@ } else { /* + * We have to unload the previous loaded DMA + * pages before trying to load a new one! + */ + bus_dmamap_unload(pc->tag, pc->map); + + /* * Try to load memory into DMA. The callback * will be called in all cases: */ @@ -639,6 +651,10 @@ void usb2_pc_cpu_invalidate(struct usb2_page_cache *pc) { + if (pc->page_offset_end == pc->page_offset_buf) { + /* nothing has been loaded into this page cache! */ + return; + } bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); return; @@ -650,6 +666,10 @@ void usb2_pc_cpu_flush(struct usb2_page_cache *pc) { + if (pc->page_offset_end == pc->page_offset_buf) { + /* nothing has been loaded into this page cache! */ + return; + } bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); return; @@ -953,6 +973,12 @@ if (size > 0) { + /* + * We have to unload the previous loaded DMA + * pages before trying to load a new one! + */ + bus_dmamap_unload(pc->tag, pc->map); + /* try to load memory into DMA using using no wait option */ if (bus_dmamap_load(pc->tag, pc->map, pc->buffer, size, NULL, BUS_DMA_NOWAIT)) { @@ -990,6 +1016,10 @@ len = pc->page_offset_end - pc->page_offset_buf; + if (len == 0) { + /* nothing has been loaded into this page cache */ + return; + } bus_dmamap_sync(pc->tag, pc->map, 0, len, BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); return; @@ -1005,6 +1035,10 @@ len = pc->page_offset_end - pc->page_offset_buf; + if (len == 0) { + /* nothing has been loaded into this page cache */ + return; + } bus_dmamap_sync(pc->tag, pc->map, 0, len, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); return;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811071811.27181.hselasky>