linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* virtual mmap basics
@ 2006-09-24 16:59 Christoph Lameter
  2006-09-25 12:28 ` Andy Whitcroft
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Lameter @ 2006-09-24 16:59 UTC (permalink / raw)
  To: linux-mm

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>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2006-09-26 15:23 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-24 16:59 virtual mmap basics Christoph Lameter
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox