Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


Thepage_addressfunction discussed above first checks whether the page is already mapped. If it does
not return a valid address, the page must be mapped usingmap_new_virtual. The function performs the
following main steps:


  1. Thepkmap_countarray is scanned backward from the last used position (held in the global
    variablelast_pkmap_nr) until a free position is found. If no position is free, the function
    sleeps until another part of the kernel performs an unmapping.
    When the maximum index ofpkmap_countis reached, the search begins at position 0. In this
    case, theflush_all_zero_pkmapsfunction is also invoked to flush the caches (you will see
    this shortly).

  2. The page tables of the kernel are modified so that the page is mapped at the desired position.
    However, the TLB is not updated.

  3. The usage counter for the new position is set to 1. As stated above, this means that the page
    is reserved but cannot be used because the TLB entries are not current.

  4. set_page_addressadds the page to the data structures of the persistent kernel mappings.


The function returns the virtual address of the newly mapped page as its result.

On architectures that do not require high-memory pages (or ifCONFIG_HIGHMEMis not set), a generic
version ofkmapis used to return only the page address without changing anything in virtual memory.

<highmem.h>
static inline void *kmap(struct page *page)
{
might_sleep();
return page_address(page);
}

Unmapping


Pages mapped withkmapmust be unmapped usingkunmapwhen they are no longer needed. As usual,
this function first checks whether the relevant page (identified by means of itspageinstance) is actually
in high memory. If so, work is delegated tokunmap_highfrommm/highmem.c, whose main task is to
decrement the counter at the corresponding position in thepkmap_countarray (I won’t discuss the
details).

This mechanism can never reduce the counter value to less than 1; this means that
the associated page is not freed. This is because of the additional usage counter
increment required to ensure correct handling of the CPU cache as discussed above.

Theflush_all_zero_pkmapsalso mentioned above is key to the final freeing of a mapping; it is always
invoked when the search for a free position inmap_new_virtualstarts from the beginning. It is responsi-
ble for three actions:


  1. flush_cache_kmapsperforms a flush on the kernel mappings (on most architectures that
    require explicit flushing, the complete CPU cache is flushed usingflush_cache_all)
    because the global page tables of the kernel are changed.^25


(^25) This is a very costly operation that fortunately is not required on many processor architectures. In this case, it is defined
as a null operation as described in Section 3.7.

Free download pdf