|
NAME
DESCRIPTIONThe kernel implements a KVM abstraction of the buffer cache which
allows it to map potentially disparate vm_page's into contiguous KVM for use
by (mainly file system) devices and device I/O. This abstraction supports
block sizes from One of the most important things to remember when
dealing with buffer pointers (struct buf) is that the
underlying pages are mapped directly from the buffer cache. No data copying
occurs in the scheme proper, though some file systems such as UFS do have to
copy a little when dealing with file fragments. The second most important
thing to remember is that due to the underlying page mapping, the
b_data base pointer in a buf is always
page-aligned, not
block-aligned.
When you have a VM buffer representing some b_offset
and b_size, the actual start of the buffer is
‘ VM buffers also keep track of a byte-granular dirty range and
valid range. This feature is normally only used by the NFS subsystem. I am
not sure why it is used at all, actually, since we have
A VM buffer is capable of mapping the underlying VM cache pages into KVM in order to allow the kernel to directly manipulate the data associated with the (vnode, b_offset, b_size). The kernel typically unmaps VM buffers the moment they are no longer needed but often keeps the struct buf structure instantiated and even bp->b_pages array instantiated despite having unmapped them from KVM. If a page making up a VM buffer is about to undergo I/O, the system typically unmaps it from KVM and replaces the page in the b_pages[] array with a place-marker called bogus_page. The place-marker forces any kernel subsystems referencing the associated struct buf to re-lookup the associated page. I believe the place-marker hack is used to allow sophisticated devices such as file system devices to remap underlying pages in order to deal with, for example, re-mapping a file fragment into a file block. VM buffers are used to track I/O operations within the kernel.
Unfortunately, the I/O implementation is also somewhat of a hack because the
kernel wants to clear the dirty bit on the underlying pages the moment it
queues the I/O to the VFS device, not when the physical I/O is actually
initiated. This can create confusion within file system devices that use
delayed-writes because you wind up with pages marked clean that are actually
still dirty. If not treated carefully, these pages could be thrown away!
Indeed, a number of serious bugs related to this hack were not fixed until
the FreeBSD 2.2.8 / FreeBSD
3.0 release. The kernel uses an instantiated VM buffer (i.e.,
struct buf) to place-mark pages in this special state.
The buffer is typically flagged The kernel reserves a portion of its KVM space to hold VM Buffer's data maps. Even though this is virtual space (since the buffers are mapped from the buffer cache), we cannot make it arbitrarily large because instantiated VM Buffers (struct buf's) prevent their underlying pages in the buffer cache from being freed. This can complicate the life of the paging system. HISTORYThe
|