docs: Update the VM swap documentation.
It was mostly up-to-date technically; a few details have been amended where things have changed, and the "personal" stuff dropped.
This commit is contained in:
@@ -1,27 +1,29 @@
|
|||||||
Swap file
|
Swap file
|
||||||
#######################
|
#######################
|
||||||
|
|
||||||
This section describes how to use swap file in Haiku and how the swap system
|
:hrev: hrev59537
|
||||||
|
|
||||||
|
This section describes how to use swap files in Haiku, and how the swap system
|
||||||
works.
|
works.
|
||||||
|
|
||||||
How to use a swap file?
|
How to use a swap file?
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Like BeOS, Haiku uses "/var/swap" as default swap file. It is created
|
Like BeOS, Haiku uses "/var/swap" as default swap file. It is created
|
||||||
during the boot process and its size is twice the size of physical memory by
|
during the boot process and its size is the size of physical memory by
|
||||||
default. You can change its size through the VirtualMemory preference
|
default, unless there's under 1GB of physical memory, in which case it's
|
||||||
|
double that. You can change its size through the VirtualMemory preference
|
||||||
application and your settings will take effect after restarting the system.
|
application and your settings will take effect after restarting the system.
|
||||||
|
|
||||||
The default swap file "/var/swap" may not satisfy your need. Haiku allows
|
The default swap file "/var/swap" may not satisfy your need. Haiku internally
|
||||||
adding/removing a swap file dynamically. (This is *NOT* implemented yet, since
|
supports adding/removing a swap file dynamically, but this functionality
|
||||||
I do not know how to add bin commands "swapon" and "swapoff" in the system.
|
isn't exposed to userspace yet.
|
||||||
It needs to be done in the future.)
|
|
||||||
|
|
||||||
How swap system works?
|
How does the swap system work?
|
||||||
======================
|
==============================
|
||||||
|
|
||||||
The virtual memory subsystem of Haiku is very similar to that of FreeBSD,
|
The virtual memory subsystem of Haiku is similar to that of FreeBSD,
|
||||||
therefore our swap system implementation is borrowed from FreeBSD.
|
therefore our swap system implementation was inspired by FreeBSD's.
|
||||||
|
|
||||||
A swap system has two main functions: (1) maintain a map between anonymous
|
A swap system has two main functions: (1) maintain a map between anonymous
|
||||||
pages and swap space, so we can page in/out when needed. (2) manage the
|
pages and swap space, so we can page in/out when needed. (2) manage the
|
||||||
@@ -30,21 +32,12 @@ Haiku.
|
|||||||
|
|
||||||
In order to maintain a map between pages and swap space, we need to record
|
In order to maintain a map between pages and swap space, we need to record
|
||||||
the pages' swap address somewhere. Here we use swap blocks. A "swap_block"
|
the pages' swap address somewhere. Here we use swap blocks. A "swap_block"
|
||||||
structure contains swap address information for 32 (value of SWAP_BLOCK_PAGES)
|
structure contains swap address information for `SWAP_BLOCK_PAGES` (32)
|
||||||
consecutive pages from a same cache. So whenever we look for a page in swap
|
consecutive pages from a same cache. So whenever we look for a page in swap
|
||||||
files, we should get the swap block for it. But how to get the swap block?
|
files, we should get the swap block for it. But how to get the swap block?
|
||||||
Here we use hash table. All swap blocks in the system are arranged into a global
|
Here we use a hash table. All swap blocks in the system are arranged into a global
|
||||||
hash table. The hash table uses a cache's address and page index in this cache
|
hash table. The hash table uses a cache's address and page index in this cache
|
||||||
as hash key.
|
as the hash key.
|
||||||
|
|
||||||
Here is an example. Suppose a page has been paged out to swap space and now
|
|
||||||
its cache wants to page it in. It works as follows: look up the swap hash table
|
|
||||||
using address of the cache and page index as hash key, if successful, we get
|
|
||||||
the swap block containing the this page's swap address. Then search the swap
|
|
||||||
block to get the exact swap address of this page. After that, we can read the
|
|
||||||
page from swap file using vfs functions.
|
|
||||||
|
|
||||||
I draw a picture and hope it could help you understand the above words.
|
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
@@ -63,40 +56,32 @@ I draw a picture and hope it could help you understand the above words.
|
|||||||
|_0__|_1__|_2__|_3__|_4__|_5__|_6__|_7__|_8__|_9__|____|__
|
|_0__|_1__|_2__|_3__|_4__|_5__|_6__|_7__|_8__|_9__|____|__
|
||||||
|
|
||||||
|
|
||||||
|
Here is an example. Suppose a page has been written out to swap space and now
|
||||||
|
its cache wants to read it in. It works as follows: look up the swap hash table
|
||||||
|
using address of the cache and page index as hash key, if successful, we get
|
||||||
|
the swap block containing the this page's swap address. Then search the swap
|
||||||
|
block to get the exact swap address of this page. After that, we can read the
|
||||||
|
page from swap file using vfs functions.
|
||||||
|
|
||||||
The swap system also manages allocation/deallocation of swap space. In our
|
The swap system also manages allocation/deallocation of swap space. In our
|
||||||
implementation, each swap file is divided into page-sized slots(called "swap
|
implementation, each swap file is divided into page-sized slots (called "swap
|
||||||
pages") and a swap file can be seen as an array of many swap pages(see the
|
pages") and a swap file can be seen as an array of many swap pages (see the
|
||||||
above picture). Swap page is the unit for swap space allocation/deallocation
|
above diagram). Swap page is the unit for swap space allocation/deallocation
|
||||||
and we use swap page index (slot index) as swap space address instead of offset.
|
and we use swap page index (slot index) as swap space address instead of offset.
|
||||||
All the swap pages in the system are given a unified address and we leave one
|
All the swap pages in the system are given a unified address and we leave one
|
||||||
page gap between two swap files. (e.g. there are 3 swap files in the system,
|
page gap between two swap files. (e.g. there are 3 swap files in the system,
|
||||||
each has 100 swap pages, the address range(to be exact, page index) for each
|
each has 100 swap pages, the address range (to be exact, page index) for each
|
||||||
swap file is: 0-99, 101-200, 202-301) Why leave a page gap between swap files?
|
swap file is: 0-99, 101-200, 202-301) Why leave a page gap between swap files?
|
||||||
Because in this way, we can easily tell if two adjacent pages are in a same
|
Because in this way, we can easily tell if two adjacent pages are in the same
|
||||||
swap file. (See the code in VMAnonymousCache::Read()).
|
swap file. (See the code in `VMAnonymousCache::Read()`).
|
||||||
|
|
||||||
The efficiency of the FreeBSD swap system lies in a special data structure:
|
The efficiency of the FreeBSD swap system lies in a special data structure:
|
||||||
radix bitmap(i.e. bitmap using radix tree for hinting.) It can operate well no
|
radix bitmap (i.e. bitmap using radix tree for hinting.) It can operate well no
|
||||||
matter how much fragmentation there is and no matter how large a bitmap is
|
matter how much fragmentation there is and no matter how large a bitmap is
|
||||||
used. I have ported the radix bitmap structure to Haiku, so our swap system
|
used. FreeBSD's radix bitmap structure was ported to Haiku and used for
|
||||||
will have a good performance. More information on radix bitmap, please look
|
the same purpose.
|
||||||
at the source code.
|
|
||||||
|
|
||||||
Swap space allocation takes place when we swap anonymous pages out.
|
Swap space allocation takes place when we write anonymous pages out. Since
|
||||||
In order to make the allocation less probable to fail, anonymous cache will
|
all VMAnonymousCaches reserve their commitments from a global "memory and
|
||||||
reserve swap space when it is initialized. If there is not enough swap space
|
swap" pool, this allocation should rarely (if ever) fail. Swap space
|
||||||
left, physical memory will be reserved. Swap space deallocation happens when
|
deallocation is triggered by the page daemon.
|
||||||
available swap space is low. The page daemon will scan a number of pages and
|
|
||||||
if the scanned page has swap space assigned, its swap space will be freed.
|
|
||||||
|
|
||||||
Acknowledgement
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Special thanks to my mentor Ingo. He is a knowledged person and always
|
|
||||||
gives me encouragement. Without his consistent and illuminating instructions,
|
|
||||||
this project would not have reached its present status.
|
|
||||||
|
|
||||||
If you find bugs or have suggestions for swap system, you can contact me
|
|
||||||
via [email protected]. Thanks in advance.
|
|
||||||
|
|
||||||
Zhao Shuai - [email protected] - 2008-08-21
|
|
||||||
|
|||||||
Reference in New Issue
Block a user