The munmap system call, which requires two parameters — the start address and length of the area to be unmapped, must be used to remove an existing mapping from virtual address space. sys_munmap is the entry point for the system call; it delegates its work in the usual way to the do_munmap function defined in mm_mmap.c. (Further implementation information is shown in the associated code flow diagram in Figure 4-13.)
The kernel must first invoke find_vma_prev to try to find the vm_area_struct instance for the region to be unmapped. This function operates in exactly the same way as find_vma discussed in Section 4.5.1, but it not only finds the vm_area_struct matching the address, but also returns a pointer to the predecessor region.
If the start address of the area to be unmapped is not precisely at the start of the region found by find_vma_prev, only part but not the whole of the mapping is unmapped. Before the kernel does this, it must first divide the existing mapping into several parts. The front part of the mapping that is not to be unmapped is first split off by split_vma. This is a helper function I won't bother discussing because all it does is perform standard operations on familiar data structures. It simply allocates a new instance of vm_area_struct, fills it with the data of the old region, and adjusts the boundaries. The new region is inserted into the data structures of the process.
The same procedure is repeated for the rear part of the mapping if the old region is not to be unmapped right up to its end.
The kernel then invokes detach_vmas_to_be_unmapped to draw up a list of all regions to be unmapped. Because an unmapping operation can involve any area of address space, it may well be that several successive regions are affected. The kernel has ensured that only complete regions are affected by splitting the areas at the start and the end.
detach_vmas_to_be_unmapped iterates over the linear list of vm_area_struct instances until the whole area is covered. The vm_next element of the structures is briefly ''misused''to link the regions to be unmapped with each other. The function also sets the mmap cache to NULL, thus invalidating it.
Two final steps follow. First, unmap_region is invoked to remove all entries from the page tables associated with the mapping. When this is done, the kernel must also make sure that the relevant entries are removed from the translation lookaside buffer or are rendered invalid. Second, the space occupied by the vm_area_struct instances is freed with remove_vma_list to finally remove the mapping from the kernel.
Continue reading here: Nonlinear Mappings
Was this article helpful?