virt_to_phys vs pgd/pmd/pte_offset calls

virt_to_phys vs pgd/pmd/pte_offset calls

Post by Timur Tab » Fri, 26 May 2000 04:00:00



I'm trying to understand the Linux memory manager, so I'm hoping someone
could answer this question for me.

I'm a little confused about the difference between the virt_to_phys
function and the combination of the pgd_offset,pmd_offset, and
pte_offset functions.

The pgd/pmd/pte stuff is used, AFAIK, to obtain a physical address of a
USER SPACE virtual address, like this:

        pgd = pgd_offset(current->mm, address);
        pmd = pmd_offset(pgd, address);
        pte = pte_offset(pmd, address);
        printk("page: %08lx\n", pte_page(*pte));

(please stop me if I say something wrong)

If I try this approach on a virtual address in a driver, this won't
work, because the driver's "virtual address" are mapped directly to
physical memory, and if I want to obtain the physical address, I need to
use the virt_to_phys macro.

In short, to obtain the physical address of a user-space virtual
address, use pgd/pmd/pte_offset.  To obtain the physical address of a
kernel-space virtual address, use virt_to_phys.

Is that correct?

--
Timur "too * for my code" Tabi
Remove "nospam_" from my email address when replying

Sent via Deja.com http://www.veryComputer.com/
Before you buy.

 
 
 

virt_to_phys vs pgd/pmd/pte_offset calls

Post by Robert Kais » Sat, 27 May 2000 04:00:00




Quote:> The pgd/pmd/pte stuff is used, AFAIK, to obtain a physical address of a
> USER SPACE virtual address, like this:

>    pgd = pgd_offset(current->mm, address);
>    pmd = pmd_offset(pgd, address);
>    pte = pte_offset(pmd, address);
>    printk("page: %08lx\n", pte_page(*pte));

> (please stop me if I say something wrong)

Looks OK to me :-)

Quote:> In short, to obtain the physical address of a user-space virtual
> address, use pgd/pmd/pte_offset.  To obtain the physical address of a
> kernel-space virtual address, use virt_to_phys.

> Is that correct?

Yes. One thing to keep in mind though: the virtual->physical
mapping that you can determine with the above algorithm may change
at any time, for instance, as a result of swapping. So, unless you
do something about it (e.g. disable interrupts or -better- lock the
pages in memory), the physical address corresponding to a user space
virtual address may change at any time without warning.

Rob

----------------------------------------------------------------
Robert Kaiser                    email: rkaiser AT sysgo DOT de
SYSGO RTS GmbH
Klein-Winternheim / Germany

 
 
 

virt_to_phys vs pgd/pmd/pte_offset calls

Post by Timur Tab » Sat, 27 May 2000 04:00:00




Quote:> Yes. One thing to keep in mind though: the virtual->physical
> mapping that you can determine with the above algorithm may change
> at any time, for instance, as a result of swapping. So, unless you
> do something about it (e.g. disable interrupts or -better- lock the
> pages in memory), the physical address corresponding to a user space
> virtual address may change at any time without warning.

Good point.  But since only a driver can travers the pgd/pmd/pte
structures, aren't interrupts and paging disabled while the driver is
running?  That is, giving a user-space virtual address that is passed to
my driver, I can obtain the physical address, do something with that,
and then exit.  The next time my driver is called, I'll need to traverse
those structures again.

Can I call a kernel API to lock that physical page down, so that I don't
have to traverse the structures every time?  If so, what is it called,
and will I have to unlock the page before the application exits (that
is, can I lock an application's memory without any consequences other
than increase memory fragmentation?)

Quote:

> Rob

> ----------------------------------------------------------------
> Robert Kaiser                    email: rkaiser AT sysgo DOT de
> SYSGO RTS GmbH
> Klein-Winternheim / Germany

--
Timur "too * for my code" Tabi
Remove "nospam_" from my email address when replying

Sent via Deja.com http://www.veryComputer.com/
Before you buy.

 
 
 

virt_to_phys vs pgd/pmd/pte_offset calls

Post by Robert Kais » Tue, 30 May 2000 04:00:00






> Good point.  But since only a driver can travers the pgd/pmd/pte
> structures, aren't interrupts and paging disabled while the driver is
> running?

Interrupts are definitely not disabled by default when driver code
is being executed. I'm not sure about paging.

Quote:>  That is, giving a user-space virtual address that is passed to
> my driver, I can obtain the physical address, do something with that,
> and then exit.

If "do something with that" involves waiting, e.g. for an interrupt,
then you can't do that. Otherwise im not sure (anyone?).

Quote:> Can I call a kernel API to lock that physical page down, so that I don't
> have to traverse the structures every time?  If so, what is it called,

There is the mlock() system call. The problem with it is that it
can only be called by root.

There is a kernel patch at ftp://ftp.sysgo.de/pub/Linux that
I once made to enable DMA from/to user-space buffers. It moves the
check for root permissions to a different place in the mlock()
syscall's execution path, thus allowing device drivers to call
the locking code without having to run from a root process.

Quote:> and will I have to unlock the page before the application exits (that
> is, can I lock an application's memory without any consequences other
> than increase memory fragmentation?)

Well, if you lock too much memory, you'll eventually bring the
system down. mlock() has a very bogus check to avoid the worst.

Note that the 2.3.x kernels seem to have a new feature (look for
"kiobuf") that allows user space DMA, so this might also do what
you need.

Cheers

Rob

----------------------------------------------------------------
Robert Kaiser                    email: rkaiser AT sysgo DOT de
SYSGO RTS GmbH
Klein-Winternheim / Germany

 
 
 

virt_to_phys vs pgd/pmd/pte_offset calls

Post by Emmanuel Dreyf » Tue, 30 May 2000 04:00:00



> In short, to obtain the physical address of a user-space virtual
> address, use pgd/pmd/pte_offset.  To obtain the physical address of a
> kernel-space virtual address, use virt_to_phys.

I understood that kernel virtual addresses were the physical addresses.
I'm now completely confused about kernel adressing mode, since I can
read in <asm/io.h> that
virt_to_phys(x) = x & ~0xc0000000

if a kernel virtual address is the physical address, I would have
expected virt_to_phys(x) = x

If anyone can explain me how it works...

--
Emmanuel Dreyfus

 
 
 

virt_to_phys vs pgd/pmd/pte_offset calls

Post by Robert Kais » Wed, 31 May 2000 04:00:00




Quote:> I understood that kernel virtual addresses were the physical addresses.
> I'm now completely confused about kernel adressing mode, since I can
> read in <asm/io.h> that
> virt_to_phys(x) = x & ~0xc0000000

Actually, it's  x & ~PAGE_OFFSET, where PAGE_OFFSET is 0xc0000000
by default, but can also be configured to assume different values.

Kernel addresses are physical address _plus_ an offset of PAGE_OFFSET.
Thus, the kernel address space is mapped linear (i.e. to convert kernel
to physical or vice versa, you just have to subtract or add an offset).

This is not the case with user space addresses. Their physical-to-
virtual mapping is nonlinear (i.e. determined by a translation table).

Quote:> if a kernel virtual address is the physical address, I would have
> expected virt_to_phys(x) = x

AFAIK, this used to be the case with older kernels (2.0.x (?)), but
it is definitely not true for the 2.2.x kernels.

Cheers

Rob

----------------------------------------------------------------
Robert Kaiser                    email: rkaiser AT sysgo DOT de
SYSGO RTS GmbH
Klein-Winternheim / Germany