Date: Sun, 01 Feb 2015 10:29:31 -0700 From: Ian Lepore <ian@freebsd.org> To: John Baldwin <jhb@freebsd.org> Cc: 'freebsd-arch' <freebsd-arch@freebsd.org> Subject: Re: Wrapper API for static bus_dma allocations Message-ID: <1422811771.15718.269.camel@freebsd.org> In-Reply-To: <2800970.jY4xzTy9Hz@ralph.baldwin.cx> References: <2800970.jY4xzTy9Hz@ralph.baldwin.cx>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 2015-01-29 at 15:37 -0500, John Baldwin wrote: [...] > +int > +bus_dma_mem_create(struct bus_dmamem *mem, bus_dma_tag_t parent, > + bus_size_t alignment, bus_addr_t lowaddr, bus_size_t len, int flags) > +{ > + struct bus_dma_mem_cb_data d; > + int error; > + > + bzero(mem, sizeof(*mem)); > + error = bus_dma_tag_create(parent, alignment, 0, lowaddr, > + BUS_SPACE_MAXADDR, NULL, NULL, len, 1, len, 0, NULL, NULL, > + &mem->dma_tag); > + if (error) { > + bus_dma_mem_free(mem); > + return (error); > + } > + error = bus_dmamem_alloc(mem->dma_tag, &mem->dma_vaddr, flags, > + &mem->dma_map); > + if (error) { > + bus_dma_mem_free(mem); > + return (error); > + } > + d.mem = mem; > + error = bus_dmamap_load(mem->dma_tag, mem->dma_map, mem->dma_vaddr, len, > + bus_dma_mem_cb, &d, BUS_DMA_NOWAIT); > + if (error == 0) > + error = d.error; > + if (error) { > + bus_dma_mem_free(mem); > + return (error); > + } > + return (0); > +} > +[...] A couple more thoughts on this... It would be good to pass the flags to both bus_dma_tag_create() and bus_dmamem_alloc(). While the manpage seems to indicate that certain flags are specific to tag-create or mem-alloc, there is actually no overlap in values, so passing flags to tag-create that a given arch only uses in mem-alloc should be harmless. Implementations may be able optimize things if they can see flags at tag-create time that normally apply to allocation. Hmmm, it just popped into my head that a new flag that means "this is going to be a combined tag+map+buffer allocation" might allow for even more optimizations. For example you can avoid allocating any resources related to bouncing if you know that the only mapping that will ever be created with that tag+map is one belonging to a buffer that the implementation can carefully allocate in a way that avoids bouncing. Another way to achieve that would be to allow the whole implementation of bus_dma_mem_create() to be supplied by the arch, rather than having it be generic in kern. The more I think about it, the more I like this. Could we eliminate the alignment arg and instead document that the alignment of the allocated buffer will be at least the same as the size argument up to PAGE_SIZE, and will be PAGE_SIZE for anything 1 page or larger? There is a standard uma-based allocator available in kern/subr_busdma_buffalloc.c that implements this behavior. It's currently used only by arm, but should be trivial to use more widely. When I investigated alignment usage a couple years ago, I found nearly all existing uses of alignment specify a value <= the size in the tag. -- Ian
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1422811771.15718.269.camel>