Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Sep 2010 20:22:14 +0200
From:      Marius Strobl <marius@alchemy.franken.de>
To:        Hans Petter Selasky <hselasky@c2i.net>
Cc:        Nathaniel W Filardo <nwf@cs.jhu.edu>, freebsd-sparc64@freebsd.org
Subject:   Re: VIMAGE hang, USB panic
Message-ID:  <20100912182214.GA90233@alchemy.franken.de>
In-Reply-To: <201007260859.20501.hselasky@c2i.net>
References:  <20100725143252.GV21929@gradx.cs.jhu.edu> <201007260859.20501.hselasky@c2i.net>

index | next in thread | previous in thread | raw e-mail

On Mon, Jul 26, 2010 at 08:59:20AM +0200, Hans Petter Selasky wrote:
> On Sunday 25 July 2010 16:32:52 Nathaniel W Filardo wrote:
> > Speaking of USB hotplug, attaching a micro 4-port hub, I get this (both
> > with and without VIMAGE):
> > 
> > ugen0.2: <vendor 0x05e3> at usbus0
> > uhub1: <vendor 0x05e3 USB2.0 Hub, class 9/0, rev 2.00/9.01, addr 2> on
> > usbus0
> > panic: iommu_dvmamap_create: bogus preallocation size , nsegments = 2,
> > maxpre = 2, maxsize = 1
> > cpuid = 0
> > KDB: stack backtrace:
> 
> Hi,
> 
> Looks like the following check fails. The allocation size USB requests is 1-
> byte. For the check to not fail, we need to request more bytes then the max-
> segments parameter specified.

Or decrease the nsegments parameter. I think that the sanity check is
right and the parameters supplied are bogus as 1 byte cannot be split
across 2 segments.

> 
>         maxpre = imin(dt->dt_nsegments, IOMMU_MAX_PRE_SEG);
>         presz = dt->dt_maxsize / maxpre;
>         KASSERT(presz != 0, ("%s: bogus preallocation size , nsegments = %d, "
>             "maxpre = %d, maxsize = %lu", __func__, dt->dt_nsegments, maxpre,
>             dt->dt_maxsize));
> 
> Does not look like a problem in the USB stack.

I think it is as the maxsize and nsegments parameters supplied in this
case make no sense. Moreover, maxsegsz should be <= maxsize, thus I'd
like to commit the following change:

Index: usb_busdma.c
===================================================================
--- usb_busdma.c	(revision 212478)
+++ usb_busdma.c	(working copy)
@@ -366,9 +366,9 @@ usb_dma_tag_create(struct usb_dma_tag *udt,
 	     /* filter    */ NULL,
 	     /* filterarg */ NULL,
 	     /* maxsize   */ size,
-	     /* nsegments */ (align == 1) ?
+	     /* nsegments */ (align == 1 && size > 1) ?
 	    (2 + (size / USB_PAGE_SIZE)) : 1,
-	     /* maxsegsz  */ (align == 1) ?
+	     /* maxsegsz  */ (align == 1 && size > USB_PAGE_SIZE) ?
 	    USB_PAGE_SIZE : size,
 	     /* flags     */ BUS_DMA_KEEP_PG_OFFSET,
 	     /* lockfn    */ &usb_dma_lock_cb,

Why is this using one more segment than splitting size in USB_PAGE_SIZE
sized segments btw? If this isn't actually needed then replacing the 2
with a 1 would be the more preferable fix IMO.

However, specifying such small allocation sizes together with
BUS_SPACE_UNRESTRICTED as nsegments, which unlike what usb(4)
currently does the I'd would consider as valid combinations,
will also trigger this assertion, so I'll remove it.

Marius



home | help

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