Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Jan 2003 02:09:50 +0100
From:      Thomas Moestl <tmoestl@gmx.net>
To:        Roderick van Domburg <r.s.a.vandomburg@student.utwente.nl>
Cc:        freebsd-sparc64@freebsd.org
Subject:   Re: panic: trap: fast data access mmu miss
Message-ID:  <20030112010950.GA56998@crow.dom2ip.de>
In-Reply-To: <LJEKLJEBPDDLMNCFCIOGEENHCAAA.r.s.a.vandomburg@student.utwente.nl>
References:  <LJEKLJEBPDDLMNCFCIOGEENHCAAA.r.s.a.vandomburg@student.utwente.nl>

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

--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sun, 2003/01/12 at 00:41:44 +0100, Roderick van Domburg wrote:
> Running on a Sun Enterprise 250 with a single UltraSparc-II CPU, 512 MB RAM
> and three Fujitsu SCSI-II hard disks. I've had this same problem with
> sources over the past few (three?) days. I had to copy this dmesg by hand,
> so please bear with any possible typos.

Please try the attached diff. The crash was due to what I consider a
driver bug (not checking the error in the bus_dmamap_load() callback),
however due to the FreeBSD busdma API being largely undocumented it is
a bit difficult to tell what should be considered legal. Much more
problematic is to assume that the first segment's bus address will be
0 in the error case. This is not currently guaranteed by any
implementation.

The attached patch fixes that, and also passes a valid pointer to the
callback for maximum compatability. It also fixes some other bugs I
came across.

This does however still not address the reason for the
bus_dmamap_load() failure; I'm not really sure why this does
happen. Please look for messages like:
 __sym_calloc2: failed to allocate ...
and tell me if you see any of them.

	- Thomas

-- 
Thomas Moestl <tmoestl@gmx.net>	http://www.tu-bs.de/~y0015675/
              <tmm@FreeBSD.org>	http://people.FreeBSD.org/~tmm/
PGP fingerprint: 1C97 A604 2BD0 E492 51D0  9C0F 1FE6 4F1D 419C 776C

--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="iommu-errbd.diff"

Index: dev/sym/sym_hipd.c
===================================================================
RCS file: /ncvs/src/sys/dev/sym/sym_hipd.c,v
retrieving revision 1.38
diff -u -r1.38 sym_hipd.c
--- dev/sym/sym_hipd.c	1 Jan 2003 18:48:52 -0000	1.38
+++ dev/sym/sym_hipd.c	12 Jan 2003 01:05:21 -0000
@@ -712,7 +712,10 @@
 {
 	bus_addr_t *baddr;
 	baddr = (bus_addr_t *)arg;
-	*baddr = segs->ds_addr;
+	if (error != 0)
+		*baddr = 0;
+	else
+		*baddr = segs->ds_addr;
 }
 
 static m_addr_t ___dma_getp(m_pool_s *mp)
@@ -728,8 +731,9 @@
 	if (bus_dmamem_alloc(mp->dmat, &vaddr,
 			      BUS_DMA_NOWAIT, &vbp->dmamap))
 		goto out_err;
-	bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr,
-			MEMO_CLUSTER_SIZE, getbaddrcb, &baddr, 0);
+	if (bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr,
+			    MEMO_CLUSTER_SIZE, getbaddrcb, &baddr, 0))
+		goto out_err;
 	if (baddr) {
 		int hc = VTOB_HASH_CODE(vaddr);
 		vbp->vaddr = (m_addr_t) vaddr;
@@ -744,8 +748,6 @@
 		bus_dmamap_unload(mp->dmat, vbp->dmamap);
 	if (vaddr)
 		bus_dmamem_free(mp->dmat, vaddr, vbp->dmamap);
-	if (vbp->dmamap)
-		bus_dmamap_destroy(mp->dmat, vbp->dmamap);
 	if (vbp)
 		__sym_mfree(&mp0, vbp, sizeof(*vbp), "VTOB");
 	return 0;
Index: sparc64/sparc64/iommu.c
===================================================================
RCS file: /ncvs/src/sys/sparc64/sparc64/iommu.c,v
retrieving revision 1.14
diff -u -r1.14 iommu.c
--- sparc64/sparc64/iommu.c	6 Jan 2003 21:59:54 -0000	1.14
+++ sparc64/sparc64/iommu.c	12 Jan 2003 00:58:39 -0000
@@ -517,7 +517,7 @@
 {
 	struct resource *res;
 	struct bus_dmamap_res *bdr;
-	bus_size_t align, bound, sgsize;
+	bus_size_t align, sgsize;
 
 	if ((bdr = malloc(sizeof(*bdr), M_IOMMU, M_NOWAIT)) == NULL)
 		return (EAGAIN);
@@ -531,9 +531,8 @@
 	sgsize = round_io_page(size) >> IO_PAGE_SHIFT;
 	if (t->dt_boundary > 0 && t->dt_boundary < IO_PAGE_SIZE)
 		panic("iommu_dvmamap_load: illegal boundary specified");
-	bound = ulmax(t->dt_boundary >> IO_PAGE_SHIFT, 1);
 	res = rman_reserve_resource_bound(&iommu_dvma_rman, 0L,
-	    t->dt_lowaddr, sgsize, bound >> IO_PAGE_SHIFT,
+	    t->dt_lowaddr, sgsize, t->dt_boundary >> IO_PAGE_SHIFT,
 	    RF_ACTIVE | rman_make_alignment_flags(align), NULL);
 	if (res == NULL)
 		return (ENOMEM);
@@ -860,7 +859,7 @@
 
 	if (error != 0) {
 		iommu_dvmamap_vunload(is, map);
-		(*cb)(cba, NULL, 0, error);
+		(*cb)(cba, sgs, 0, error);
 	} else {
 		/* Move the map to the end of the LRU queue. */
 		iommu_map_insq(map);
Index: kern/subr_rman.c
===================================================================
RCS file: /ncvs/src/sys/kern/subr_rman.c,v
retrieving revision 1.27
diff -u -r1.27 subr_rman.c
--- kern/subr_rman.c	27 Nov 2002 03:55:22 -0000	1.27
+++ kern/subr_rman.c	12 Jan 2003 00:43:52 -0000
@@ -229,7 +229,7 @@
 		 */
 		do {
 			rstart = (rstart + amask) & ~amask;
-			if (((rstart ^ (rstart + count)) & bmask) != 0)
+			if (((rstart ^ (rstart + count - 1)) & bmask) != 0)
 				rstart += bound - (rstart & ~bmask);
 		} while ((rstart & amask) != 0 && rstart < end &&
 		    rstart < s->r_end);

--UlVJffcvxoiEqYs2--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-sparc" in the body of the message




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