Getting the physical address of kmalloc's memory

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
No, this is not a 'google first' post. (Or at least I hope it isn't, because
I did spend some serious time already on this. :-) )

I work on ARM, and am writing a device driver. The problem is that I have a
peace of memory I dynamically allocate with kmalloc( ..,..,GPF_KERNEL). Now
our embedded device has a DMA-unit, which of course doesn't want to see the
return address of kmalloc, because it is virtual.

Now, the question is whether:

virt_to_phys( kmalloc_return_address )

gives me the physical address. Some posters at Google say 'yes', other say
'no' and again others say it depends on the platform. The latter therefore
doesn't sound logical.

On ARM, I suspect it is not, because my system violently crashes if I feed
this address to my DMA-unit. If I then take a fixed physical address and via
ioremap get a virtual address (actually a cookie, but on ARM this is
fortunately the same, which made testing easy), and do a virt_to_phys on
that cookie, I indeed don't get back my physical address. So this strengthes
me in my assumtion, virt_to_phys does something, but not what I hoped/some
believe ... (*)

So the first question is: What does virts_to_phys actually do (all all
platforms)?


Second question is, because I found the function consistent_alloc. This
function which is as I understood ARM and PPC only, and allocates a
uncached, but also unbuffered peace of memory (The latter is at least not
achived with kmalloc). However, it also gives me the hardware-address. So,
in my case this should solve the problem, but this still makes me wonder,
what developers on other platforms have to do to get a physical address of a
kmalloc-ed peace of memory.


So the second question: Does there exists a portable method at all?


Or am I missing somnething completely? In that case please educate me. :-)

Regards,

Armin

(*) Although it seems that for IA32 this behaviour is 'normal' in the way,
that virt_to_phys is not defibed for ioremap-ed addresses. However, in the
case - as on ARM - where cookies and virtual addresses are by luck
identical, this shouldn't matter since thevirt-to_phys function/macro cannot
tell of course whether it is a cookie or 'true' virtual address.



Re: Getting the physical address of kmalloc's memory
Quoted text here. Click to load it

Armin,

try to use virt_to_bus(). The comments in linux/include/asm-arm/memory.h
suggest, that it may be the function you're looking for.

j.


Re: Getting the physical address of kmalloc's memory
Quoted text here. Click to load it
[...]
Armin,

try to use virt_to_bus(). The comments in linux/include/asm-arm/memory.h
suggest, that it may be the function you're looking for.

j.



Re: Getting the physical address of kmalloc's memory

Quoted text here. Click to load it


Doesn't work. Actually I found the answer in the Linux Documentation thanks
to some poster in another group ...

It seems that all virt_to_xxxx calls should not be used for _this purpose_.

On some platforms it may work, but that is not portable and also not the
intended use of the functions. So in short: They do not what the name might
suggest.

The answer lays in:

/usr/src/linux/Documentation/DMA-mapping.txt

which explains some variants of consistent_alloc as used on ARM/PPC. These
variants are supposed to be platform-independent.

Regards,

Armin



Re: Getting the physical address of kmalloc's memory
Quoted text here. Click to load it

Usually the allocated buffer can consist of multiple pieces. So a single
virt_to_phys( kmalloc_return_address ) does not describe it. I suppose
there is a function (but not kmalloc) that allocates memory in a single
piece for DMA use. Of course this will fail if the system was running
for some time, as not larger pieces of sequential RAM are existing any
more.

-Michael

Re: Getting the physical address of kmalloc's memory

Quoted text here. Click to load it

Nope.  kmalloc()/get_free_pages(), et. al.,  memory is always contiguous.
A single virt_to_phys() will work fine.  However, vmalloc() memory is
_not_ necessarily contiguous but nobody would ever consider DMA into
vmalloc()'ed memory ;-)


Re: Getting the physical address of kmalloc's memory

Quoted text here. Click to load it


Not with kmalloc ...
It is guaranteed to be consecutive blocks. Actually, that's why one must use
kmalloc instead of vmalloc for DMA-units or similar tasks. (BTW
consistent_alloc does the same.)

Armin



Re: Getting the physical address of kmalloc's memory

Quoted text here. Click to load it

I did a little looking around and it seems to me that you need to give
kmalloc the GFP_ATOMIC parameter to get a single consecutive block.

-Michael

Re: Getting the physical address of kmalloc's memory
Sorry, my hint to GPF_ATOMIC seems to be misleading,

but I found that there is a flag __GPF_DMA, that might to be set if the
block needs to be accessed by DMA.

-Michael

Re: Getting the physical address of kmalloc's memory
Quoted text here. Click to load it

Thanks anyway. Note, that I shouldn't use kmalloc at all, since there is no
direct way of getting its physical address afterwards. It turned out that
virt_to_xxxx do NOT do what the name may suggest and a lot of people think
it does! It is NOT a generic way to translate between physical/bus and
virtual addresses. What it mostly does is add a few offsets related to
pages. On some platforms that may be enough for some specific usecases, but
on other platforms and usecases it does not.

Simply said: don't use virt_to_xxxx in drivers at all, for translating
between physical and virtual addressed of memory allocated with kmalloc,
since it will not be guaranteed to work.

However, if you use the pci_alloc_consistent functions it works in a
portable way. The name is misleading, since it cabn also be used for non-PCI
devices. Simplypass on NULL for the PCI-device descriptor.
On ARM, one can also use alloc_consistent, which is actually the
ARM-implementation of the pci-function if one looks at the source. However,
the same GFP_XXX parameters apply  there (where in case of
pci_alloc_consistent the GFP_DMA is automaticly added, while in
consistent_alloc it is not and one has to do it oneself), so your comment
was still very helpfull

Regards,

Armin



Site Timeline