linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Lameter <clameter@sgi.com>
To: linux-mm@kvack.org
Subject: virtual mmap basics
Date: Sun, 24 Sep 2006 09:59:17 -0700 (PDT)	[thread overview]
Message-ID: <Pine.LNX.4.64.0609240959060.18227@schroedinger.engr.sgi.com> (raw)

Lets say we have memory of MAX_PFN pages.

Then we need a page struct array with MAX_PFN page structs to manage
that memory called mem_map.

For mmap processing without virtualization (FLATMEM) (simplified)
we have:

#define pfn_valid(pfn)		(pfn < max_pfn)
#define pfn_to_page(pfn)	&mem_map[pfn]
#define page_to_pfn(page)     	(page - mem_map))

which is then used to build the commonly used functions:

#define virt_to_page(kaddr)     pfn_to_page(kaddr >> PAGE_SHIFT)
#define page_address(page)	(page_to_pfn(page) << PAGE_SHIFT)

Virtual Memmory Map
-------------------

For a virtual memory map we reserve a virtual memory area
VMEMMAP_START ... VMEMMAP_START + max_pfn * sizeof(page_struct))
vmem_map is defined to be a pointer to struct page. It is a constant
pointing to VMEMMAP_START. 

We use page tables to manage the virtual memory map. Page tables
may be sparse. Pages in the area used for page structs may be missing.
Software may dynamically add new page table entries to make new
ranges of pfn's valid. Its like sparse.

The basic functions then become:

#define pfn_valid(pfn)		(pfn < max_pfn && valid_page_table_entry(pfn))
#define pfn_to_page(pfn)	&vmem_map[pfn]
#define page_to_pfn(page)     	(page - vmem_map))

We only loose (apart from additional TLB use if this memory was not 
already using page tables) on pfn_valid when we have to traverse the page 
table via valid_page_table_entry() if the processor does not have an 
instruction to check that condition. We could avoid the page table 
traversal by having the page fault handler deal with it somehow. But then 
pfn_valid is not that frequent an operation.

virt_to_page and page_to_virt remain unchanged.

Sparse
------

Sparse currently does troublesome lookups for virt_to_page
and page_address.

#define page_to_pfn(pg) (pg - 
	section_mem_map_addr(nr_to_section(page_to_section(pg)))

#define pfn_to_page(pfn)
	 section_mem_map_addr(pfn_to_section(pfn)) + __pfn;

page_to_section is an extraction of flags from page->flags.

static inline struct mem_section *nr_to_section(unsigned long nr)
{
        if (!mem_section[SECTION_NR_TO_ROOT(nr)])
                return NULL;
        return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
}

static inline struct page *section_mem_map_addr(struct mem_section 
*section)
{
        unsigned long map = section->section_mem_map;
        map &= SECTION_MAP_MASK;
        return (struct page *)map;
}

So we have a mininum of a couple of table lookups and one page->flags 
retrieval (okay that may be argued to be in cache) in virt_to_page versus 
*none* in the virtual memory map case. Similar troublesome code is
there fore the reverse case.

pfn_valid requires at least 3 lookups. Which may be equivalent
to walking to page table over 3 levels if the processor has no command to 
make the hardware do it.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

             reply	other threads:[~2006-09-24 16:59 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-24 16:59 Christoph Lameter [this message]
2006-09-25 12:28 ` Andy Whitcroft
2006-09-25 16:27   ` Christoph Lameter
2006-09-25 17:11     ` Christoph Lameter
2006-09-25 21:05       ` Christoph Lameter
2006-09-25 22:22         ` Andy Whitcroft
2006-09-25 23:37           ` Christoph Lameter
2006-09-26 12:06             ` Andy Whitcroft
2006-09-25 18:09     ` Andy Whitcroft
2006-09-25 21:00       ` Christoph Lameter
2006-09-25 23:54         ` virtual memmap sparsity: Dealing with fragmented MAX_ORDER blocks Christoph Lameter
2006-09-26  0:31           ` Christoph Lameter
2006-09-26 12:11             ` Andy Whitcroft
2006-09-26 15:23               ` Christoph Lameter
2006-09-26  8:16           ` Mel Gorman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.64.0609240959060.18227@schroedinger.engr.sgi.com \
    --to=clameter@sgi.com \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox