[haiku-development] modifed:a genearl introduction to Haiku vm

  • From: "Zhao Shuai" <upczhsh@xxxxxxx>
  • To: <haiku-development@xxxxxxxxxxxxx>
  • Date: Sun, 13 Apr 2008 22:40:09 +0800

Hi,

I modified the article introducing the Haiku vm system. Thanks to Axel and 
Travis, they have pointed out my mistakes.

There still must be mistakes. If you find bugs, please let me know.

BTW: Writing a technical document is not easy for me. Though I spent one day 
modifying, it is not satisfying yet. 
I will continue working on it...

Time to sleep, bye.


A General Introduction to Haiku Virtual Memory Management
The Major Facilities of Haiku Virtual Memory System
There are 5 key data structures in the system that handles the virtual memory 
management:

l        vm_address_space: structure that describes the virtual address space 
of a process. 

l        vm_area: structure that represents a virtually contiguous range of 
address space that shares protection and inheritance attributes

l        vm_page: structure that represents one physical memory page.

l        vm_cache: structure that describes a source of data for a range of 
addresses

l        vm_store: structure that contains data necessary to support swapping 

All of the structures listed above are defined in 
trunk\headers\private\kernel\arch\vm_types.h.

Virtual Address Space
The vm_address_space structure encapsulates the virtual memory information of a 
particular process. It’s defined as:

struct vm_address_space {

    struct vm_area      *areas; 

    struct vm_area      *area_hint;

    sem_id              sem; 

    addr_t              base;          

    addr_t              size;

    int32               change_count;

    vm_translation_map  translation_map;

    team_id             id;

    int32               ref_count;

    int32               fault_count;

    int32               state;

    addr_t              scan_va;

    addr_t              working_set_size;

    addr_t              max_working_set;

    addr_t              min_working_set;

    bigtime_t           last_working_set_adjust;

    struct vm_address_space *hash_next;

};

Two fields of vm_address_space should be noticed: one is areas: a pointer to 
its linked list of areas(see below); the other is translation_map , which 
contains the virtual to physical address translation information.

Virtual Memory Areas
An area is a chunk of virtual memory of any size. A process divides its linear 
virtual address space into a number of areas(regions). For example, a simple 
process may have several areas for its process binary, heap, stack and 
shared-libraries respectively. (To see how many areas a process contains, use 
the listarea command in the terminal).

An area can be mapped from a file or it can use the “anonymous memory”. Areas 
for process binaries and shared-libraries are mapped from files and will be 
filled in with the appropriate content when first accessed. Uninitiated data 
(e.g. heap and stack) use anonymous memory. It is zero filled and its contents 
are abandoned when the last reference is dropped.

The vm_area structure is defined as follows:

struct vm_area {

    char                *name; 

    area_id             id;

    addr_t              base; 

    addr_t              size;

    uint32              protection; 

    uint16              wiring;

    uint16              memory_type;

    

struct vm_cache     *cache; 

    vint32              no_cache_change;

    off_t               cache_offset;

    uint32              cache_type;

    vm_area_mappings    mappings;

 

    struct vm_address_space *address_space;

    struct vm_area      *address_space_next;

    struct vm_area      *cache_next;

    struct vm_area      *cache_prev;

    struct vm_area      *hash_next;

};

The address_space field tells which address space it belongs to and the base 
and size fields give the position of the area in the address space. Each 
vm_area is associated with a single vm_cache which really holds the data(see 
below) and the cache field points to the right vm_cache. 

Page Cache
vm_cache contains a list of pages that stores the data. The structure makes 
easy share between different virtual memory areas. For example, if two areas in 
the same/different process are mapped from the same file, they will point to 
the same vm_cache

The definition of vm_cache is listed below:

struct vm_cache {

    mutex               lock;

    struct vm_area      *areas;

    vint32              ref_count;

    struct list_link    consumer_link;

    struct list         consumers;      

    vm_page             *page_list;

    struct vm_cache     *source;

    struct vm_store     *store;

    off_t               virtual_base;

    off_t               virtual_size;

    uint32              page_count;

    uint32              temporary : 1;

    uint32              scan_skip : 1;

    uint32              busy : 1;

    uint32              type : 5;

};

Pages are cached in the same vm_cache mainly because they share one backing 
store (e.g. files, block device, swap). The store field in the vm_cache points 
to the right backing store(see below).

Pages
Physical Memory is divided into fixed size pieces called pages. The vm_page 
structure is used to describe one physical page and each physical frame has 
associated with a vm_page structure.

struct vm_page {

    struct vm_page      *queue_prev;

    struct vm_page      *queue_next;

    struct vm_page      *hash_next;

    addr_t              physical_page_number;

    struct vm_cache     *cache;

    uint32              cache_offset;

    struct vm_page      *cache_prev;

    struct vm_page      *cache_next;

    vm_page_mappings    mappings;

    uint8               type : 2;

    uint8               state : 3;

    uint8               is_cleared : 1;

    uint8               busy_writing : 1;

    uint16              wired_count;

    int8                usage_count;

};

Each page of physical memory is associated with a vm_cache; the cache 
identifies the backing store for the page. 

Pages are also categorized through the placement of their respective vm_page 
structures on one of several paging queues. There are 5 types of queues for 
storing pages: sFreePageQueue, sClearPageQueue, sModifiedPageQueue, 
sInactivePageQueue, sActivePageQueue: 

Backing Stores
A backing store is a place for data to live when it is not resident. In the 
case of a memory-mapped file, the backing store is the file itself. When the 
kernel needs to evict from physical memory a page that is backed by a file, it 
can simply discard the page unless the page has been modified while it was 
resident, in which case the change can be committed to the backing store.

The vm_store structure provides the mechanism by which data are moved between 
backing store and physical memory. The major component of vm_store is a number 
of registered functions that defines its operation.

struct vm_store {

    struct vm_store_ops *ops;

    struct vm_cache     *cache;

    off_t               committed_size;

};

 

typedef struct vm_store_ops {

    void (*destroy)(struct vm_store *backingStore);

    status_t (*commit)(struct vm_store *backingStore, off_t size);

    bool (*has_page)(struct vm_store *backingStore, off_t offset);

    status_t (*read)(struct vm_store *backingStore, off_t offset,

        const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter);

    status_t (*write)(struct vm_store *backingStore, off_t offset,

        const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter);

    status_t (*fault)(struct vm_store *backingStore,

        struct vm_address_space *aspace, off_t offset);

    status_t (*acquire_unreferenced_ref)(struct vm_store *backingStore);

    void (*acquire_ref)(struct vm_store *backingStore);

    void (*release_ref)(struct vm_store *backingStore);

} vm_store_ops;

Link them together
The figure below shows how these structures are linked together. In this case, 
two vm_areas are mapped from the same part of a file, so they share a vm_cache.



Figure 1  Link all the structures together

GIF image

Other related posts: