views:

179

answers:

2

I had a driver for linux kernel (2.6.18) in which I used kmalloc(sizeof(my_struct_t), GFP_ATOMIC) to allocate memory which was later used for data transfer using DMA controller of some device. Later I had to increase the size of my_struct. It became too large so that the kmalloc() code used static assertion and compiled __you_cannot_kmalloc_that_much symbol to notify that chunks of memory are too large to alloc. So I thought I will declare the my_struct_t as static variable and won't have to allocate it at all.

I defined static my_struct_t my_struct;

but the DMA transaction didn't worked well and I got invalid data DMA'd to the buffer.

My question is: it forbidden to use static (global) buffers for dma? And if yes then where exactly in the kernel memory map those buffers sit.

Thanks

+3  A: 

The problem will come that if you are allocating memory on the stack you cannot guarantee that the memory is in a contiguous physical block of memory. If it isn't then you can't DMA it.

Wouldn't it just be easier to break your DMA transfer up into multiple blocks that you CAN kmalloc? You can then send n DMA transfers instead of just 1. It will make precious little difference to your bus utilisation and will work, unlike your current issue.

Goz
actually I am not allocating on stackI use global variable which is allocated at some data section inside kernel module. The section is loaded to kernel memory I assumed that this section sitting at continues and dma'able memory. Can someone give more details about what actually going on when kernel memory is loaded to kernel memory
budevg
Its still unlikely to get allocated into physical ram. Usually a program is loaded into virtual memory and hence you can no longer guarantee the block is contiguous ...
Goz
+3  A: 

You generally can't take any old memory and use it for DMA. The problem is that your memory area may cross page boundaries and be split up across different areas of physical memory. Also, it might get swapped out, and later swapped back in to a different physical location from before. On some architectures there are regions of memory that aren't visible from the device bus at all. You may sometimes be lucky enough that your improperly-acquired DMA buffers work, but it's not guaranteed.

Check out the dma allocation functions like dma_alloc_coherent(). Also LDD3 Chapter 15.

If you have problems allocating DMA buffers because they're too big, then you have another problem, requiring that you either split up your DMA transfers manually, or use scatter-gather DMA.

Eric Seppanen