I have a driver that calls __pa() on an address obtained via vmalloc(). This is not
supposed to work, and yet oddly it appears to. Is there a possibility, even a remote one,
that __pa() will return the correct physical address for a buffer returned by the
vmalloc() function?
Also, does the pgd/pmd/pte page-table walking work on addresses returned by kmalloc(), or
do I have to use __pa() to get the physical address?
--
Timur Tabi
Staff Software Engineer
[email protected]
One thing a Southern boy will never say is,
"I don't think duct tape will fix it."
-- Ed Smylie, NASA engineer for Apollo 13
On Fri, May 27, 2005 at 02:26:36PM -0500, Timur Tabi wrote:
> I have a driver that calls __pa() on an address obtained via vmalloc().
> This is not supposed to work, and yet oddly it appears to. Is there a
> possibility, even a remote one, that __pa() will return the correct
> physical address for a buffer returned by the vmalloc() function?
It will return the correct physical address for the start of the buffer.
But given that vmalloc is a non-contingous allocator that's pretty useless.
As are physical addresses for anything but low-level architecture code.
Christoph Hellwig wrote:
> It will return the correct physical address for the start of the buffer.
> But given that vmalloc is a non-contingous allocator that's pretty useless.
So as long as the vmalloc'd memory fits inside one page, __pa() will always give the
correct address? If so, then can't I just call __pa() for every page in the buffer and
get a list of physical addresses? If I can do that, then how the memory be virtually
contiguous but not physicall contiguous?
> As are physical addresses for anything but low-level architecture code.
I don't understand what that means.
--
Timur Tabi
Staff Software Engineer
[email protected]
One thing a Southern boy will never say is,
"I don't think duct tape will fix it."
-- Ed Smylie, NASA engineer for Apollo 13
On Freedag 27 Mai 2005 21:54, Timur Tabi wrote:
> Christoph Hellwig wrote:
>
> > It will return the correct physical address for the start of the buffer.
No, not even that. If you do __pa(vmalloc()), the result will point outside of
the physical address space on most architectures.
> > But given that vmalloc is a non-contingous allocator that's pretty useless.
>
> So as long as the vmalloc'd memory fits inside one page, __pa() will always give the
> correct address? If so, then can't I just call __pa() for every page in the buffer and
> get a list of physical addresses? If I can do that, then how the memory be virtually
> contiguous but not physicall contiguous?
If the vmalloc'd memory fits into one page, you should not have used
vmalloc in the first place ;-). The only reason to ever use vmalloc
is if you can't get enough memory from alloc_pages reliably.
> > As are physical addresses for anything but low-level architecture code.
>
> I don't understand what that means.
It means that a device driver should never need to use __pa directly, because
physical addresses don't have a well-defined meaning outside of the memory
management. A driver should only need to deal with user virtual, kernel virtual
and bus virtual but never real addresses.
Also, no device driver should be using vmalloc either: vmalloc fragments
your address space, pins physical pages and eats small children.
Arnd <><
On Fri, May 27, 2005 at 08:29:25PM +0100, Christoph Hellwig wrote:
> On Fri, May 27, 2005 at 02:26:36PM -0500, Timur Tabi wrote:
> > I have a driver that calls __pa() on an address obtained via vmalloc().
> > This is not supposed to work, and yet oddly it appears to. Is there a
> > possibility, even a remote one, that __pa() will return the correct
> > physical address for a buffer returned by the vmalloc() function?
>
> It will return the correct physical address for the start of the buffer.
__pa() is only defined to works on the direct-mapped kernel region.
The fact that it works on some architectures should be viewed as a
bug.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
Timur Tabi <[email protected]> writes:
> Also, does the pgd/pmd/pte page-table walking work on addresses
> returned by kmalloc(), or do I have to use __pa() to get the physical
> address?
You should use vmalloc_to_page() (this does the page-table walking
with correct locking), then the usual dma mapping interface
(pci_map_page() or pci_map_sg()) to get bus address(es) you can pass
to your device for DMA.
Gerd
Gerd Knorr wrote:
> You should use vmalloc_to_page() (this does the page-table walking
> with correct locking), then the usual dma mapping interface
> (pci_map_page() or pci_map_sg()) to get bus address(es) you can pass
> to your device for DMA.
My problem is that I don't know where the memory came from. It could have been allocated
via kmalloc, or vmalloc, or anywhere else. Can I call vmalloc_to_page() on memory
allocated via kmalloc()? If the answer is no, then how can I tell whether the memory was
allocated via vmalloc() or some other method? I need a reliable virtual-to-physical (or
virtual-to-bus, which is the same thing on x86 architectures) method for any memory address.
--
Timur Tabi
Staff Software Engineer
[email protected]
One thing a Southern boy will never say is,
"I don't think duct tape will fix it."
-- Ed Smylie, NASA engineer for Apollo 13
On Tue, May 31, 2005 at 10:51:27AM -0500, Timur Tabi wrote:
> Gerd Knorr wrote:
>
> >You should use vmalloc_to_page() (this does the page-table walking
> >with correct locking), then the usual dma mapping interface
> >(pci_map_page() or pci_map_sg()) to get bus address(es) you can pass
> >to your device for DMA.
>
> My problem is that I don't know where the memory came from.
Can you fix that? If so, try that. Would be the best.
> It could have been allocated via kmalloc, or vmalloc, or
> anywhere else. Can I call vmalloc_to_page() on memory
> allocated via kmalloc()?
I think you can't. What is "anywhere else"? Does that include
userspace addresses?
> If the answer is no, then how can I tell whether the memory
> was allocated via vmalloc() or some other method?
Not sure how portable that is, but comparing the vaddr against
the vmalloc address space could work. There are macros for
that, VMALLOC_START & VMALLOC_END IIRC.
> I need a reliable virtual-to-physical (or virtual-to-bus,
> which is the same thing on x86 architectures)
Well, on !x86 architectures it isn't ...
Gerd
--
-mm seems unusually stable at present.
-- akpm about 2.6.12-rc3-mm3
Gerd Knorr wrote:
> Can you fix that? If so, try that. Would be the best.
No, I cannot. The memory is passed to my driver from some other driver that I do not
control.
> I think you can't. What is "anywhere else"? Does that include
> userspace addresses?
No, but it might include the stack.
> Not sure how portable that is, but comparing the vaddr against
> the vmalloc address space could work. There are macros for
> that, VMALLOC_START & VMALLOC_END IIRC.
Thanks, I'll try that.
I still haven't gotten an answer to my question about whether pgd/pud/pmd/pte_offset will
obtain the physical address for a kmalloc'd buffer.
--
Timur Tabi
Staff Software Engineer
[email protected]
One thing a Southern boy will never say is,
"I don't think duct tape will fix it."
-- Ed Smylie, NASA engineer for Apollo 13
On Tue, May 31, 2005 at 01:59:53PM -0500, Timur Tabi wrote:
> I still haven't gotten an answer to my question about whether
> pgd/pud/pmd/pte_offset will obtain the physical address for a
> kmalloc'd buffer.
No it won't.
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
Timur Tabi wrote:
> Gerd Knorr wrote:
>
>> Can you fix that? If so, try that. Would be the best.
>
>
> No, I cannot. The memory is passed to my driver from some other driver
> that I do not
> control.
What kind of driver are you writing, and what other driver is giving you
this address?
>> I think you can't. What is "anywhere else"? Does that include
>> userspace addresses?
>
> No, but it might include the stack.
>
>> Not sure how portable that is, but comparing the vaddr against
>> the vmalloc address space could work. There are macros for
>> that, VMALLOC_START & VMALLOC_END IIRC.
>
>
> Thanks, I'll try that.
>
> I still haven't gotten an answer to my question about whether
> pgd/pud/pmd/pte_offset will obtain the physical address for a kmalloc'd
> buffer.
Walking the page tables isn't guaranteed to work for all addresses on
all arches. On some you have to deal with large pages, on others you
have parts of the address space that are mapped by different mechanisms.
This isn't something that drivers should be getting involved in.
--
Brian Gerst