Add VM section

This commit is contained in:
Matthew Dillon 1999-02-06 20:20:17 +00:00
parent bb771e769c
commit 41530b5ac2
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=4230
4 changed files with 171 additions and 4 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.33 1998-07-23 10:27:04 wosch Exp $
# $Id: Makefile,v 1.34 1999-02-06 20:20:16 dillon Exp $
.NOTPARALLEL:
@ -10,7 +10,7 @@ SRCS+= disks.sgml diskless.sgml dma.sgml eresources.sgml esdi.sgml
SRCS+= firewalls.sgml german.sgml glossary.sgml goals.sgml
SRCS+= handbook.sgml history.sgml hw.sgml install.sgml isdn.sgml
SRCS+= kerberos.sgml kernelconfig.sgml kerneldebug.sgml kernelopts.sgml
SRCS+= lists.sgml mail.sgml makeworld.sgml memoryuse.sgml
SRCS+= lists.sgml mail.sgml makeworld.sgml memoryuse.sgml vm.sgml
SRCS+= mirrors.sgml nfs.sgml nutshell.sgml pgpkeys.sgml policies.sgml
SRCS+= porting.sgml ports.sgml ppp.sgml printing.sgml
SRCS+= quotas.sgml relnotes.sgml routing.sgml russian.sgml

View file

@ -1,4 +1,4 @@
<!-- $Id: handbook.sgml,v 1.98 1999-02-05 17:17:42 wosch Exp $ -->
<!-- $Id: handbook.sgml,v 1.99 1999-02-06 20:20:16 dillon Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!DOCTYPE linuxdoc PUBLIC "-//FreeBSD//DTD linuxdoc//EN" [
@ -174,6 +174,7 @@ or one of the numerous
<chapt><heading>FreeBSD Internals</heading>
&booting;
&memoryuse;
&vm;
&dma;

View file

@ -1,4 +1,4 @@
<!-- $Id: sections.sgml,v 1.30 1998-04-30 12:51:14 jkh Exp $ -->
<!-- $Id: sections.sgml,v 1.31 1999-02-06 20:20:17 dillon Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!-- Entities containing all the pieces of the handbook are -->
@ -38,6 +38,7 @@
<!ENTITY mail SYSTEM "mail.sgml">
<!ENTITY makeworld SYSTEM "makeworld.sgml">
<!ENTITY memoryuse SYSTEM "memoryuse.sgml">
<!ENTITY vm SYSTEM "vm.sgml">
<!ENTITY mirrors SYSTEM "mirrors.sgml">
<!ENTITY nfs SYSTEM "nfs.sgml">
<!ENTITY nutshell SYSTEM "nutshell.sgml">

165
handbook/vm.sgml Normal file
View file

@ -0,0 +1,165 @@
<!-- $Id: vm.sgml,v 1.1 1999-02-06 20:20:17 dillon Exp $ -->
<!-- The FreeBSD Documentation Project -->
<sect><heading>The FreeBSD VM System<label id="vm"></heading>
<p><em>Contributed by &a.dillon;.<newline>
6 Feb 1999.</em>
<em>An involved description of FreeBSD's VM internals</em>
<sect1><heading>Management of physical memory - vm_page_t</heading>
<p>
Physical memory is managed on a page-by-page basis through the
<em>vm_page_t</em> structure. Pages of physical memory are
categorized through the placement of their respective vm_page_t
structures on one of several paging queues.
<p>
A page can be in a wired, active, inactive, cache, or free state.
Except for the wired state, the page is typically placed in a doubly
link list queue representing the state that it is in. Wired pages
are not placed on any queue.
<p>
FreeBSD implements a more involved paging queue for cached and free
pages in order to implement page coloring. Each of these states
involves multiple queues arranged according to the size of the
processor's L1 and L2 caches. When a new page needs to be allocated,
FreeBSD attempts to obtain one that is reasonably well aligned from
the point of view of the L1 and L2 caches relative to the VM object the
page is being allocated for.
<p>
Additionally, a page may be held with a reference count or locked
with a busy count. The VM system also implements an 'ultimate locked'
state for a page using the PG_BUSY bit in the page's flags.
<p>
In general terms, each of the paging queues operates in a LRU fashion.
A page is typicaly placed in a wired or active state initially. When
wired, the page is usually associated with a page table somewhere.
The VM system ages the page by scanning pages in a more active paging
queue (LRU) in order to move them to a less-active paging queue. Pages
that get moved into the cache are still associated with a VM object
but are candidates for immediate reuse. Pages in the free queue are
truely free. FreeBSD attempts to minimize the number of pages in the
free queue, but a certain minimum number of truely free pages must be
maintained in order to accomodate page allocation at interrupt time.
<p>
If a process attempts to access a page that does not exist in its
page table but does exist in one of the paging queues ( such as the
inactive or cache queues), a relatively inexpensive page reactivation
fault occurs which causes the page to be reactivated. If the page
does not exist in system memory at all, the process must block while
the page is brought in from disk.
<p>
FreeBSD dynamically tunes its paging queues and attempts to maintain
reasonable ratios of pages in the various queues as well as attempts
to maintain a reasonable breakdown of clean vs dirty pages. The
amount of rebalancing that occurs depends on the system's memory load.
This rebalancing is implemented by the pageout daemon and involves
laundering dirty pages ( syncing them with their backing store ),
noticing when pages are activity referenced ( resetting their position
in the LRU queues or moving them between queues ), migrating pages
between queues when the queues are out of balance, and so forth.
FreeBSD's VM system is willing to take a reasonable number of
reactivation page faults to determine how active or how idle a page
actually is. This leads to better decisions being made as to when
to launder or swap-out a page.
<sect1><heading>The unified buffer cache - vm_object_t</heading>
<p>
FreeBSD implements the idea of a generic 'VM object'. VM objects
can be associated with backing store of various types - unbacked,
swap-backed, physical device-backed, or file-backed storage. Since
the filesystem uses the same VM objects to manage in-core data relating
to files, the result is a unified buffer cache.
<p>
VM objects can be <em>shadowed</em>. That is, they can be stacked on
top of each other. For example, you might have a swap-backed VM object
stacked on top of a file-backed VM object in order to implement a
MAP_PRIVATE mmap()ing. This stacking is also used to implement various
sharing properties, including, copy-on-write, for forked address
spaces.
<p>
It should be noted that a vm_page_t can only be associated with one
VM object at a time. The VM object shadowing implements the
perceived sharing of the same page across multiple instances.
<sect1><heading>Filesystem I/O - struct buf</heading>
<p>
vnode-backed VM objects, such as file-backed objects, generally need
to maintain their own clean/dirty info independant from the VM system's
idea of clean/dirty. For example, when the VM system decides to
synchronize a physical page to its backing store, the VM system needs
to mark the page clean before the page is actually written to its
backing s tore. Additionally, filesystems need to be able to map
portions of a file or file metadata into KVM in order to operate on it.
<p>
The entities used to manage this are known as filesystem buffers,
<em>struct buf</em>'s, and also known as <em>bp</em>'s. When a
filesystem needs to operate on a portion of a VM object, it typically
maps part of the object into a struct buf and the maps the pages in
the struct buf into KVM. In the same manner, disk I/O is typically
issued by mapping portions of objects into buffer structures and
then issuing the I/O on the buffer structures. The underlying
vm_page_t's are typically busied for the duration of the I/O.
Filesystem buffers also have their own notion of being busy, which
is useful to filesystem driver code which would rather operate on
filesystem buffers instead of hard VM pages.
<p>
FreeBSD reserves a limited amount of KVM to hold mappings from struct
bufs, but it should be made clear that this KVM is used solely to
hold mappings and does not limit the ability to cache data. Physical
data caching is strictly a function of vm_page_t's, not filesystem
buffers. However, since filesystem buffers are used placehold I/O,
they do inherently limit the amount of concurrent I/O possible. As
there are usually a few thousand filesystem buffers available, this
is not usually a problem.
<sect1><heading>Mapping Page Tables - vm_map_t, vm_entry_t</heading>
<p>
FreeBSD separates the physical page table topology from the VM
system. All hard per-process page tables can be reconstructed on
the fly and are usually considered throwaway. Special page tables
such as those managing KVM are typically permanently preallocated.
These page tables are not throwaway.
<p>
FreeBSD associates portions of vm_objects with address ranges in
virtual memory through vm_map_t and vm_entry_t structures. Page
tables are directly synthesized from the vm_map_t/vm_entry_t/
vm_object_t hierarchy. Remember when I mentioned that physical pages
are only directly associated with a vm_object. Well, that isn't
quite true. vm_page_t's are also linked into page tables that they
are actively associated with. One vm_page_t can be linked into
several <em>pmaps</em>, as page tables are called. However, the
hierarchical association holds so all references to the same
page in the same object reference the same vm_page_t and thus give
us buffer cache unification across the board.
<sect1><heading>KVM Memory Mapping</heading>
<p>
FreeBSD uses KVM to hold various kernel structures. The single
largest entity held in KVM is the filesystem buffer cache. That is,
mappings relating to struct buf entities.
<p>
Unlike Linux, FreeBSD does NOT map all of physical memory into KVM.
This means that FreeBSD can handle memory configurations up to 4G
on 32 bit platforms. In fact, if the mmu were capable of it, FreeBSD
could theoretically handle memory configurations up to 8TB on a 32
bit platform. However, since most 32 bit platforms are only capable
of mapping 4GB of ram, this is a moot point.
<p>
KVM is managed through several mechanisms. The main mechanism used to
manage KVM is the <em>zone allocator</em>. The zone allocator takes
a chunk of KVM and splits it up into constant-sized blocks of memory
in order to allocate a specific type of structure. You can use the
<tt>vmstat -m</tt> command to get an overview of current KVM
utilization broken down by zone.
<p>
<em>Contributed by &a.dillon;.<newline>
6 Feb 1999.</em>