Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Nov 2018 14:24:44 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Rajesh Kumar <rajfbsd@gmail.com>
Cc:        freebsd-drivers@freebsd.org, freebsd-hackers@freebsd.org
Subject:   Re: bus_dmamem_alloc doesn't follow alignment specified
Message-ID:  <20181127122444.GB2378@kib.kiev.ua>
In-Reply-To: <CAAO%2BANMNFv5UBG1H7hOziW1DWVMGNTRp4ZQcGCF29XS-SwpG7g@mail.gmail.com>
References:  <CAAO%2BANMNFv5UBG1H7hOziW1DWVMGNTRp4ZQcGCF29XS-SwpG7g@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Nov 27, 2018 at 04:37:57PM +0530, Rajesh Kumar wrote:
> Hi,
> 
> I am writing a PCI-E driver, where I am trying to allocate DMA buffers. But
> seems, like the alignment requirements are not satisfied by
> bus_dmamem_alloc function. I am using stable/11 branch.
> 
> *Code :*
> dma_setup(size, align, alimit)  {
> 
>     printf ("size 0x%x align 0x%x alimit 0x%x\n", size, align, alimit);
> 
>      if (bus_dma_tag_create(parent, align, 0,
>                alimit, BUS_SPACE_MAXADDR,
>                 NULL, NULL, size, 1, size,
>                 0, NULL, NULL, &dma_tag)) {
>                 return (ENOMEM);
>     }
> 
>     if (bus_dmamem_alloc(dma_tag, &virt_addr,
>                 BUS_DMA_WAITOK | BUS_DMA_ZERO, &dma_map)) {
>                     bus_dma_tag_destroy(dma_tag);
>                     return (ENOMEM);
>     }
> 
>     if (bus_dmamap_load(dma_tag, dma_map, virt_addr,
>                 size, dma_cbfn, &arg, BUS_DMA_NOWAIT)) {
>                    bus_dmamem_free(dma_tag, virt_addr, dma_map);
>                    bus_dma_tag_destroy(mw->dma_tag);
>                    return (ENOMEM);
>    }
> 
>    printf("dma_addr 0x%lx virt_addr 0x%lx\n", (uint64_t)arg->addr,
> (uint64_t)virt_addr);
> 
> }
> 
> dma_cbfn(void *tmp, bus_dma_segment_t *segs, int nsegs, int error)
> {
>         struct dma_args *arg = (struct dma_args *)tmp;
>         arg->addr = segs[0].ds_addr;
> }
> 
> *Logs: *
> size 0x100000 align 0x100000 alimit 0xffffffff
> dma_addr *0x78e00000*  virt_addr *0xfffffe1c3665f000*
> 
> As seen above, dma_addr is as per alignment requirement, but virtual
> address from bus_dmamem_alloc doesn't seem to satisfy the alignment
> requirement).
> 
> My understanding is both the DMA addr and the virtual address should be as
> per the alignment specified.  Can anyone please clarify?

Only bus address is aligned.

For single-segment i.e. contiguous allocations, amd64 could benefit from
using dmap VA instead of kmem_alloc.  This would be only an optimization,
not done right now.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20181127122444.GB2378>