Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Jul 2003 18:28:17 -0700
From:      John-Mark Gurney <gurney_j@efn.org>
To:        Juli Mallett <jmallett@freebsd.org>
Cc:        freebsd-current@freebsd.org
Subject:   Re: USB crappiness?
Message-ID:  <20030721012817.GC917@funkthat.com>
In-Reply-To: <20030719194215.A6668@FreeBSD.org>
References:  <20030719194215.A6668@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Juli Mallett wrote this message on Sat, Jul 19, 2003 at 19:42 -0500:
> I tried to upgrade my workstation to current recently, and I have to
> use a lot of USB, and while using some USB mass storage device, with
> a UFS filesystem on it, and doing a large operation to it (tar c|tar x)
> everything deadlocked on ufs, the USB stack blew up, and upon causing
> an interrupt to it, it panicked, and panic pagefaulted.
> 
> Anyone else seeing these sorts of cohesive fallovers?

Ok, I think I know the problem now.  It's a big different between NetBSD
and FreeBSD's bus_dma code.  In NetBSD, they keep the same bus_dma_tag_t,
but in FreeBSD it is encouraged/required to create a new tag for sets of
allocations because of size (we can't do a bus_dmamem_alloc w/ a size).
So, in usb_allocmem, the tag equality doesn't work and allocated a full
page for each 64byte allocation.  This quickly causes kmem to get exhusted.

ohci doesn't have this problem since it has it's own allocator for small
sizes.

this patch should fix it temporarily while I investigate a more complete
fix (xterm pasted):
Index: usb_mem.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/usb_mem.c,v
retrieving revision 1.1
diff -u -r1.1 usb_mem.c
--- usb_mem.c   2003/07/15 22:42:37     1.1
+++ usb_mem.c   2003/07/21 01:26:38
@@ -256,6 +259,8 @@
                        return (err);
                }
                b->fullblock = 0;
+               /* XXX - override the tag */
+               b->tag = tag;
                for (i = 0; i < USB_MEM_BLOCK; i += USB_MEM_SMALL) {
                        f = (struct usb_frag_dma *)((char *)b->kaddr + i);
                        f->block = b;

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030721012817.GC917>