I am trying to use a Linux DMA driver. Currently, when I send the transaction out and begin waiting, my request times out. I believe this has to do with the way I am setting up my buffers when I am performing DMA Mapping.
char *src_dma_buffer = kmalloc(dma_length, GFP_KERNEL);
char *dest_dma_buffer = kzalloc(dma_length, GFP_KERNEL);
tx_dma_handle = dma_map_single(tx_chan->device->dev, src_dma_buffer, dma_length, DMA_TO_DEVICE);
rx_dma_handle = dma_map_single(rx_chan->device->dev, dest_dma_buffer, dma_length, DMA_FROM_DEVICE);
In Xilinx's DMA driver, they take special care to look at memory alignment. In particular, they use a property of the dma_chan->dma_device called copy_align.
- @copy_align: alignment shift for memcpy operations
const int dma_length = 16*1024;
len = dmatest_random() % test_buf_size + 1;
len = (len >> align) << align;
if (!len)
len = 1 << align;
src_off = dmatest_random() % (test_buf_size - len + 1);
dst_off = dmatest_random() % (test_buf_size - len + 1);
src_off = (src_off >> align) << align;
dst_off = (dst_off >> align) << align;
It looks like that original address is totally random from dmatest_random(). Not sure what can be said/what guarentees can be made about that memory.
static unsigned long dmatest_random(void)
{
unsigned long buf;
get_random_bytes(&buf, sizeof(buf));
return buf;
}
They then use these offsets to set up their source and destination buffers for DMA.
u8 *buf = thread->srcs[i] + src_off;
dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len, DMA_MEM_TO_DEV);
I am very confused as to what this does. My only guess is that it will page align the beginning of the source and destination buffers in virtual memory.
Looking at the way I set up my buffers with kmalloc and kzalloc, do I have any guarantee that my buffers start at page boundaries? Am I right in that I need my buffers to start at page boundaries?
The source code to the Xilinx DMA test driver is here: https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/axidmatest.c
You can find the high level description of the problem I am trying to solve here: https://forums.xilinx.com/t5/Embedded-Linux/AXI-DMA-Drivers-for-Kernel-v-4-9-PetaLinux-2017-3/td-p/828917