El 09/11/15 a les 20.19, Ian Lepore ha escrit: > On Mon, 2015-11-09 at 16:41 +0100, Roger Pau Monné wrote: >> Hello, >> >> El 09/11/15 a les 13.30, Hans Petter Selasky ha escrit: >>> On 11/09/15 13:19, Roger Pau Monné wrote: >>>> + if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) { >>>> + /* >>>> + * If we have to keep the offset of each page this >>>> function >>>> + * is not suitable, switch back to >>>> bus_dmamap_load_ma_triv >>>> + * which is going to do the right thing in this case. >>>> + */ >>>> + error = bus_dmamap_load_ma_triv(dmat, map, ma, buflen, >>>> ma_offs, >>>> + flags, segs, segp); >>>> + return (error); >>>> + } >>> >>> Hi, >>> >>> There has been an update made to the USB stack, which is currently >>> the >>> only client of "BUS_DMA_KEEP_PG_OFFSET", which means this check can >> >> The only in-tree client. We don't know if there are other clients out >> of >> the tree. >> > > The BUS_DMA_KEEP_PG_OFFSET flag is not documented anywhere except in a > short coment block near its #define which is less than 100% rigorous in > specifying exactly what the flag even means. For example it is > documented as being a "hint" but also includes the word "must". It > doesn't say whether the flag is to be used to create a tag, to create a > map, or to load a buffer. It says the offset must be kept the same in > the first segment but doesn't really fully explain what the USB > requirements are (and the flag was added specifically for USB). > > To me, all of that adds up to freedom to clarify the meaning of the > flag in both code and documentation without a lot of worrying about out > of tree code. And the mips and arm busdma implementations are soon > going to leverage that freedom into much better implementations based > on the new understanding of what that flag really requires.
Maybe rename the flag to BUS_DMA_CONTIGUOUS_PG_OFFSET? >>> probably be skipped or relaxed a bit. The condition which must be >>> fullfilled is: >> >> So you basically want a contiguous bounce buffer. I don't think we >> can >> just change BUS_DMA_KEEP_PG_OFFSET to mean "use a contiguous bounce >> buffer". Maybe a new flag could be introduced to describe this new >> requirement and the old one deprecated. >> > > It's not "I want a contiguous buffer". It is "I want contiguous > offsets when transitioning between (potentially non-continguous) > pages." That grants you the freedom to bounce a couple different ways > depending on what's most efficient for the platform and the situation. > > For example, you can maintain the offset-within-page in the first > segment and allow the offset in all subsequent pages (bounced or not) > to be zero. That's what all current implementations are doing, but it > can require two full bounce pages to handle a 2-byte transfer that > happens to be split across two pages (and yes that happens; it's not > even rare in USB, as lots of DMA is done specifying buffers and > variables on kernel stacks or in softc member variables). > > It also allows for the possibility of changing the offset in the first > segment if doing so avoids any page crossings at all (which handles > everything from the 2-byte worst case to a 4096-byte buffer). Yes, that's what I've now tried to do in x86: https://reviews.freebsd.org/D4119 Change the offset in the first segment and then making sure everything is contiguous in terms of offsets. >>> #ifdef USB_DEBUG >>> if (nseg > 1 && >>> ((segs->ds_addr + segs->ds_len) & (USB_PAGE_SIZE - 1)) >>> != >>> ((segs + 1)->ds_addr & (USB_PAGE_SIZE - 1))) { >>> /* >>> * This check verifies there is no page offset hole >>> * between the first and second segment. See the >>> * BUS_DMA_KEEP_PG_OFFSET flag. >>> */ >>> DPRINTFN(0, "Page offset was not preserved\n"); >>> error = 1; >>> goto done; >>> } >>> #endif >> >> AFAICT with the current bounce implementation on x86 you would have >> to >> specify an alignment of PAGE_SIZE in order to have this guarantee >> without specifying BUS_DMA_KEEP_PG_OFFSET. >> >> IMHO, we should change all the current bounce buffer code and switch >> to >> use memdescs for everything (ie: bios and mbufs should use a memdesc >> internally). Then each arch should provide functions to copy from the >> different kinds of memdescs (either memdescs containing physical or >> virtual memory), so the bounce code could be unified between all >> arches. >> Of course that's easier said than done... >> > > I completely disagree with this, mostly because I'm halfway through a > set of changes that will make arm and mips bounce handling look > completely different than x86 or other platforms. That reflects the > differences in underlying hardware that leads to completely different > reasons for bouncing in the first place. > > x86 code bounces DMA when there are exclusion regions in the physical > address space where DMA cannot occur. On ARM and MIPS that situation > just basically never occurs (except maybe on a few ancient arm xscale > systems), and virtually all bouncing is due to DMA buffers not being on > cache line boundaries. Because bio and mbuf DMA typically is cache > -aligned, that means that almost all bouncing is a handful of bytes at > a time, and the page-replacement bounce scheme that was copied from x86 > just isn't efficient (in fact it wastes megabytes of memory in > preallocated bounce buffers that small-memory arm and mips systems > can't really afford to waste). I see, I guess you are right that other arches have very different requirements in terms of bouncing, and that unifying them wouldn't work that well. I got that conclusion after looking at some of the busdma implementations for other arches which right now look quite similar, didn't know there was a major rework planned. Roger. _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"