Date: Sun, 12 Jan 2003 23:55:18 +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: <20030112225517.GB278@crow.dom2ip.de> In-Reply-To: <LJEKLJEBPDDLMNCFCIOGAENLCAAA.r.s.a.vandomburg@student.utwente.nl> References: <20030112010950.GA56998@crow.dom2ip.de> <LJEKLJEBPDDLMNCFCIOGAENLCAAA.r.s.a.vandomburg@student.utwente.nl>
next in thread | previous in thread | raw e-mail | index | archive | help
--XsQoSWH+UP9D9v3l Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, 2003/01/12 at 16:13:20 +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. > > Thanks for the patches! Unfortunately however, it still doesn't seem to > attach sym1 quite right, I believe. Your patches did make the booting > process advance further, but the kernel failed to mount root. Here is the > dmesg, once again manually copied. That __sym_calloc2 message is right on > the second line. Hmmm, that's what I expected. Can you please try the attached patch instead? It adds some more error reporting, so I should be able to see what exactly is going wrong. Please mail me any new lines of output appearing directly above the __sym_calloc2 message. I think I've already ruled out most causes; I'm suspecting that malloc() might be failing due to massive use of M_NOWAIT in the related code. - 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 --XsQoSWH+UP9D9v3l Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="iommu-errbd.diff" 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 22:43:59 -0000 @@ -517,10 +517,13 @@ { 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) + if ((bdr = malloc(sizeof(*bdr), M_IOMMU, M_NOWAIT)) == NULL) { + printf("iommu_dvma_valloc: res descriptor allocation " + "failed.\n"); return (EAGAIN); + } /* * If a boundary is specified, a map cannot be larger than it; however * we do not clip currently, as that does not play well with the lazy @@ -531,12 +534,13 @@ 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) + if (res == NULL) { + printf("iommu_dvma_valloc: out of DVMA space.\n"); return (ENOMEM); + } bdr->dr_res = res; bdr->dr_used = 0; @@ -766,8 +770,10 @@ pmap_t pmap = NULL; KASSERT(buflen != 0, ("iommu_dvmamap_load_buffer: buflen == 0!")); - if (buflen > dt->dt_maxsize) + if (buflen > dt->dt_maxsize) { + printf("iommu_dvmamap_load_buffer: buffer too long.\n"); return (EINVAL); + } if (td != NULL) pmap = vmspace_pmap(td->td_proc->p_vmspace); @@ -813,6 +819,8 @@ sgcnt++; if (sgcnt >= dt->dt_nsegments || sgcnt >= BUS_DMAMAP_NSEGS) { + printf("iommu_dvmamap_load_buffer: too many " + "segments.\n"); error = EFBIG; break; } @@ -860,7 +868,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: 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: 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 22:45:20 -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); @@ -263,8 +263,11 @@ * two new allocations; the second requires but one. */ rv = malloc(sizeof *rv, M_RMAN, M_NOWAIT | M_ZERO); - if (rv == 0) + if (rv == 0) { + printf("rman_reserve_resource: out of " + "memory.\n"); goto out; + } rv->r_start = rstart; rv->r_end = rstart + count - 1; rv->r_flags = flags | RF_ALLOCATED; @@ -282,6 +285,8 @@ */ r = malloc(sizeof *r, M_RMAN, M_NOWAIT|M_ZERO); if (r == 0) { + printf("rman_reserve_resource: out of " + "memory.\n"); free(rv, M_RMAN); rv = 0; goto out; --XsQoSWH+UP9D9v3l-- 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?20030112225517.GB278>