Date: Mon, 17 Jun 2013 20:40:16 +0000 (UTC) From: Scott Long <scottl@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r251868 - in stable/9/sys: arm/arm mips/mips Message-ID: <201306172040.r5HKeGRq032770@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: scottl Date: Mon Jun 17 20:40:16 2013 New Revision: 251868 URL: http://svnweb.freebsd.org/changeset/base/251868 Log: MFC r240177: Dynamically allocate the S/G lists passed to callback routines rather than allocating them on the stack of various bus_dmamap_load*() functions. The S/G lists are stored in the DMA tags. This matches the implementation on all other platforms. Submitted by: jhb Approved by: marius, adrian Obtained from: Netflix Modified: stable/9/sys/arm/arm/busdma_machdep.c stable/9/sys/mips/mips/busdma_machdep.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/arm/arm/busdma_machdep.c ============================================================================== --- stable/9/sys/arm/arm/busdma_machdep.c Mon Jun 17 20:27:20 2013 (r251867) +++ stable/9/sys/arm/arm/busdma_machdep.c Mon Jun 17 20:40:16 2013 (r251868) @@ -81,6 +81,7 @@ struct bus_dma_tag { int map_count; bus_dma_lock_t *lockfunc; void *lockfuncarg; + bus_dma_segment_t *segments; /* * DMA range for this tag. If the page doesn't fall within * one of these ranges, an error is returned. The caller @@ -374,6 +375,8 @@ bus_dma_tag_create(bus_dma_tag_t parent, newtag->lockfunc = dflt_lock; newtag->lockfuncarg = NULL; } + newtag->segments = NULL; + /* * Take into account any restrictions imposed by our parent tag */ @@ -447,7 +450,6 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) #endif if (dmat != NULL) { - if (dmat->map_count != 0) return (EBUSY); @@ -457,6 +459,8 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) parent = dmat->parent; atomic_subtract_int(&dmat->ref_count, 1); if (dmat->ref_count == 0) { + if (dmat->segments != NULL) + free(dmat->segments, M_DEVBUF); free(dmat, M_DEVBUF); /* * Last reference count, so @@ -484,6 +488,17 @@ bus_dmamap_create(bus_dma_tag_t dmat, in bus_dmamap_t newmap; int error = 0; + if (dmat->segments == NULL) { + dmat->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, + M_NOWAIT); + if (dmat->segments == NULL) { + CTR3(KTR_BUSDMA, "%s: tag %p error %d", + __func__, dmat, ENOMEM); + return (ENOMEM); + } + } + newmap = _busdma_alloc_dmamap(); if (newmap == NULL) { CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM); @@ -585,6 +600,16 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi mflags = M_NOWAIT; else mflags = M_WAITOK; + if (dmat->segments == NULL) { + dmat->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, + mflags); + if (dmat->segments == NULL) { + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", + __func__, dmat, dmat->flags, ENOMEM); + return (ENOMEM); + } + } if (flags & BUS_DMA_ZERO) mflags |= M_ZERO; @@ -883,11 +908,6 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_ { vm_offset_t lastaddr = 0; int error, nsegs = -1; -#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif KASSERT(dmat != NULL, ("dmatag is NULL")); KASSERT(map != NULL, ("dmamap is NULL")); @@ -898,14 +918,14 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_ map->buffer = buf; map->len = buflen; error = bus_dmamap_load_buffer(dmat, - dm_segments, map, buf, buflen, kernel_pmap, + dmat->segments, map, buf, buflen, kernel_pmap, flags, &lastaddr, &nsegs); if (error == EINPROGRESS) return (error); if (error) (*callback)(callback_arg, NULL, 0, error); else - (*callback)(callback_arg, dm_segments, nsegs + 1, error); + (*callback)(callback_arg, dmat->segments, nsegs + 1, error); CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", __func__, dmat, dmat->flags, nsegs + 1, error); @@ -921,11 +941,6 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { -#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif int nsegs = -1, error = 0; M_ASSERTPKTHDR(m0); @@ -941,7 +956,7 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, for (m = m0; m != NULL && error == 0; m = m->m_next) { if (m->m_len > 0) { error = bus_dmamap_load_buffer(dmat, - dm_segments, map, m->m_data, m->m_len, + dmat->segments, map, m->m_data, m->m_len, pmap_kernel(), flags, &lastaddr, &nsegs); map->len += m->m_len; } @@ -954,9 +969,9 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, /* * force "no valid mappings" on error in callback. */ - (*callback)(callback_arg, dm_segments, 0, 0, error); + (*callback)(callback_arg, dmat->segments, 0, 0, error); } else { - (*callback)(callback_arg, dm_segments, nsegs + 1, + (*callback)(callback_arg, dmat->segments, nsegs + 1, m0->m_pkthdr.len, error); } CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", @@ -1012,11 +1027,6 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, int flags) { vm_offset_t lastaddr = 0; -#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif int nsegs, i, error; bus_size_t resid; struct iovec *iov; @@ -1048,8 +1058,8 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, caddr_t addr = (caddr_t) iov[i].iov_base; if (minlen > 0) { - error = bus_dmamap_load_buffer(dmat, dm_segments, map, - addr, minlen, pmap, flags, &lastaddr, &nsegs); + error = bus_dmamap_load_buffer(dmat, dmat->segments, + map, addr, minlen, pmap, flags, &lastaddr, &nsegs); map->len += minlen; resid -= minlen; @@ -1060,9 +1070,9 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, /* * force "no valid mappings" on error in callback. */ - (*callback)(callback_arg, dm_segments, 0, 0, error); + (*callback)(callback_arg, dmat->segments, 0, 0, error); } else { - (*callback)(callback_arg, dm_segments, nsegs+1, + (*callback)(callback_arg, dmat->segments, nsegs+1, uio->uio_resid, error); } Modified: stable/9/sys/mips/mips/busdma_machdep.c ============================================================================== --- stable/9/sys/mips/mips/busdma_machdep.c Mon Jun 17 20:27:20 2013 (r251867) +++ stable/9/sys/mips/mips/busdma_machdep.c Mon Jun 17 20:40:16 2013 (r251868) @@ -80,6 +80,7 @@ struct bus_dma_tag { int map_count; bus_dma_lock_t *lockfunc; void *lockfuncarg; + bus_dma_segment_t *segments; struct bounce_zone *bounce_zone; }; @@ -352,6 +353,8 @@ bus_dma_tag_create(bus_dma_tag_t parent, newtag->lockfunc = dflt_lock; newtag->lockfuncarg = NULL; } + newtag->segments = NULL; + /* * Take into account any restrictions imposed by our parent tag */ @@ -434,6 +437,8 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) parent = dmat->parent; atomic_subtract_int(&dmat->ref_count, 1); if (dmat->ref_count == 0) { + if (dmat->segments != NULL) + free(dmat->segments, M_DEVBUF); free(dmat, M_DEVBUF); /* * Last reference count, so @@ -442,7 +447,7 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) */ dmat = parent; } else - dmat = NULL; + dmat = NULL; } } CTR2(KTR_BUSDMA, "%s tag %p", __func__, dmat_copy); @@ -461,6 +466,17 @@ bus_dmamap_create(bus_dma_tag_t dmat, in bus_dmamap_t newmap; int error = 0; + if (dmat->segments == NULL) { + dmat->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, + M_NOWAIT); + if (dmat->segments == NULL) { + CTR3(KTR_BUSDMA, "%s: tag %p error %d", + __func__, dmat, ENOMEM); + return (ENOMEM); + } + } + newmap = _busdma_alloc_dmamap(); if (newmap == NULL) { CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM); @@ -563,6 +579,16 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi mflags = M_NOWAIT; else mflags = M_WAITOK; + if (dmat->segments == NULL) { + dmat->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF, + mflags); + if (dmat->segments == NULL) { + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", + __func__, dmat, dmat->flags, ENOMEM); + return (ENOMEM); + } + } if (flags & BUS_DMA_ZERO) mflags |= M_ZERO; @@ -824,11 +850,6 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_ { vm_offset_t lastaddr = 0; int error, nsegs = -1; -#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif KASSERT(dmat != NULL, ("dmatag is NULL")); KASSERT(map != NULL, ("dmamap is NULL")); @@ -839,14 +860,14 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_ map->buffer = buf; map->len = buflen; error = bus_dmamap_load_buffer(dmat, - dm_segments, map, buf, buflen, kernel_pmap, + dmat->segments, map, buf, buflen, kernel_pmap, flags, &lastaddr, &nsegs); if (error == EINPROGRESS) return (error); if (error) (*callback)(callback_arg, NULL, 0, error); else - (*callback)(callback_arg, dm_segments, nsegs + 1, error); + (*callback)(callback_arg, dmat->segments, nsegs + 1, error); CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", __func__, dmat, dmat->flags, nsegs + 1, error); @@ -862,11 +883,6 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { -#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif int nsegs = -1, error = 0; M_ASSERTPKTHDR(m0); @@ -882,7 +898,7 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, for (m = m0; m != NULL && error == 0; m = m->m_next) { if (m->m_len > 0) { error = bus_dmamap_load_buffer(dmat, - dm_segments, map, m->m_data, m->m_len, + dmat->segments, map, m->m_data, m->m_len, kernel_pmap, flags, &lastaddr, &nsegs); map->len += m->m_len; } @@ -895,9 +911,9 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, /* * force "no valid mappings" on error in callback. */ - (*callback)(callback_arg, dm_segments, 0, 0, error); + (*callback)(callback_arg, dmat->segments, 0, 0, error); } else { - (*callback)(callback_arg, dm_segments, nsegs + 1, + (*callback)(callback_arg, dmat->segments, nsegs + 1, m0->m_pkthdr.len, error); } CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", @@ -953,11 +969,6 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, int flags) { vm_offset_t lastaddr = 0; -#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif int nsegs, i, error; bus_size_t resid; struct iovec *iov; @@ -990,8 +1001,8 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, caddr_t addr = (caddr_t) iov[i].iov_base; if (minlen > 0) { - error = bus_dmamap_load_buffer(dmat, dm_segments, map, - addr, minlen, pmap, flags, &lastaddr, &nsegs); + error = bus_dmamap_load_buffer(dmat, dmat->segments, + map, addr, minlen, pmap, flags, &lastaddr, &nsegs); map->len += minlen; resid -= minlen; @@ -1002,9 +1013,9 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, /* * force "no valid mappings" on error in callback. */ - (*callback)(callback_arg, dm_segments, 0, 0, error); + (*callback)(callback_arg, dmat->segments, 0, 0, error); } else { - (*callback)(callback_arg, dm_segments, nsegs+1, + (*callback)(callback_arg, dmat->segments, nsegs+1, uio->uio_resid, error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306172040.r5HKeGRq032770>