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>