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>
next 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