Библиотека сайта rus-linux.net
The book is available and called simply "Understanding The Linux Virtual Memory Manager". There is a lot of additional material in the book that is not available here, including details on later 2.4 kernels, introductions to 2.6, a whole new chapter on the shared memory filesystem, coverage of TLB management, a lot more code commentary, countless other additions and clarifications and a CD with lots of cool stuff on it. This material (although now dated and lacking in comparison to the book) will remain available although I obviously encourge you to buy the book from your favourite book store :-) . As the book is under the Bruce Perens Open Book Series, it will be available 90 days after appearing on the book shelves which means it is not available right now. When it is available, it will be downloadable from http://www.phptr.com/perens so check there for more information.
To be fully clear, this webpage is not the actual book.
Next: 10.3 Mapping High Memory Up: 10. High Memory Management Previous: 10.1 Managing the PKMap   Contents   Index
Subsections
10.2 Mapping High Memory Pages
The kmap pool is quite small so it is important that users of kmap()
call kunmap()
as quickly as possible because the pressure on this
small window grows incrementally worse as the size of high memory grows
in comparison to low memory. The API for mapping pages from high memory is
described in Table 10.1.
The kmap()
function itself is fairly simple. It first checks to
make sure an interrupt is not calling this function(as it may sleep) and
calls out_of_line_bug()
if true. An interrupt handler calling
BUG()
would panic the system so out_of_line_bug()
prints out bug information and exits cleanly.
It then checks if the page is already in low memory and simply returns
the address if it is. This way, users that need kmap()
may use it
unconditionally knowing that if it is already a low memory page, the function
is still safe. If it is a high page to be mapped, kmap_high()
is called to begin the real work.
The kmap_high()
function begins with checking the
page
virtual
field which is set if the page is already
mapped. If it is NULL, map_new_virtual()
provides a mapping
for the page.
Creating a new virtual mapping with map_new_virtual()
is a
simple case of linearly scanning pkmap_count
. The scan starts at
last_pkmap_nr
instead of 0 to prevent searching over the same
areas repeatedly between kmap()
s. When last_pkmap_nr
wraps around to 0, flush_all_zero_pkmaps()
is called to set all
entries from 1 to 0 before flushing the TLB.
If, after another scan, an entry is still not found, the process sleeps on
the pkmap_map_wait
wait queue until it is woken up after the
next kunmap()
.
Once a mapping has been created, the corresponding entry in
the pkmap_count
array is incremented and the virtual address in
low memory returned.
10.2.1 Unmapping Pages
The kunmap()
function, like its complement, performs
two checks. The first is an identical check to kmap()
for
usage from interrupt context. The second is that the page is below
highmem_start_page
. If it is, the page already exists in low
memory and needs no further handling. Once established that it is a page to
be unmapped, kunmap_high()
is called to perform the unmapping.
The kunmap_high()
is simple in principle. It decrements the
corresponding element for this page in pkmap_count
. If it reaches 1
(remember this means no more users but a TLB flush is required), any process
waiting on the pkmap_map_wait
is woken up as a slot is now
available. The page is not unmapped from the page tables then as that would
require a TLB flush. It is delayed until flush_all_zero_pkmaps()
is called.
Next: 10.3 Mapping High Memory Up: 10. High Memory Management Previous: 10.1 Managing the PKMap   Contents   Index Mel 2004-02-15