Memory Management
Memory Management
Memory Management
.
The memory management unit allows each process to have its own address space. Each
process has its own page table, so the same virtual address can exist in her two different page
frames in two different processes. The operating system manages page tables for each process.
During a context switch, the operating system must notify the processor's memory management
unit that it should use a different page table. This is done by modifying the page table base
register (the register containing the starting address of the page table).
Each page table entry, in addition to storing the corresponding page frame, contains
various page table entries indicating whether the page is valid (whether there is a corresponding
page frame) and how the page is accessed (read only, execute, only). It can also store flags.
Whether the page was accessed or modified (in kernel mode).
There are generally two optimizations in the memory management unit. One optimizes seek time and the other
optimizes the space used by the page table.
1. If each address translation requires a page table lookup, memory access performance is twice as slow because the
page table must be read in addition to accessing the desired memory location. This overhead is reduced by translation
lookaside buffers (TLBs) that cache frequently used page table entries in associative memory.
2nd Most processes use only a small portion of the available virtual address space, resulting in large areas of page
tables that contain no entries. Hierarchical structures are often used to help manage the size of the page table. Virtual
address page bits are divided into two parts. The high bit defines the offset into the topmost index table. This index
table contains the base register of the partial page table. The low order bits of the page bits define the offset within this
partial page table.
Most processors support two modes of operation: a virtual addressing mode, which uses address translation by the
memory management unit, and a physical addressing mode, which bypasses the MMU. In this latter mode, each
memory reference is a reference to an actual physical memory location within the memory system. Since the page
tables are not yet set up, the CPU boots in physical addressing mode on power up. The system normally remains in
physical addressing mode while the operating system is loading and running to initialize the page tables. The
operating system then switches the processor to virtual addressing mode.
In current operating systems, the memory view is divided into two logical regions: kernel
memory and process memory. Kernel memory is memory reserved for the operating system
kernel's code, data, and stack. Its position in the virtual address space remains constant and is
usually at the top of the address space. On 32-bit Linux systems, kernel memory is configurable
(PAGE_OFFSET) and is typically set in the top 1 GB of the address space. On Microsoft
Windows 7 systems, the top 2 GB of address space is mapped to kernel memory on 32-bit
systems (8 TB on 64-bit systems).
process memory represents the remaining address space and is available for user processes. In
physical memory, page frames are allocated to various processes. Virtual memory, on the other
hand, looks at memory in terms of the context of the process. The view of memory is defined by
a process's page table, which contains a mapping to the pages associated with that particular
process and a mapping to the kernel. If a mode switch is caused by a
interrupt or system call, the current page table is unchanged. A mode switch is occurring, not a
context switch. Execution is transferred to the kernel and memory can be accessed as needed in
the context of the process that spawned the mode switch. Page tables are typically set up to
disallow user-mode execution access to regions of the address space that are mapped into
kernel memory.
The Linux operating system maintains an array named free_area that contains a list of free pages. The first element of
the array is a list of free single-page regions. The second element is a list of free two-sided regions (adjacent free
faces). The third element is a list of free rectangular regions. etc The
buddy algorithm is a memory allocation and management algorithm that manages memory in powers of two. This
brief description shows only a basic list of blocks of free memory chunks. Buddy algorithm; there are some variations
to it. A list of blocks of free memory blocks.
The ARM MMU supports fourpage sizes. The largest sizes are called sections and the smaller
sizes are called pages:
Supersections: 16 MB memory blocks (24-bit offsets)
Sections: 1 MB memory
blocks (20-bit offsets)
Large pages: 64 KB pages (16-bit offsets)
Small pages: 4 KB pages (12-bit offsets)
first-level table containseither a pointer to a second-level tables (partial page
tables) or a base address of a section or a supersection. Hence, if we use the really
big pages — sections and supersections — then we don't have to go through two
levels of hierarchy. The benefit of sections and supersections is that you can have
a large region of memory, such as the operating system, mapped using just a
single entry in the TLB.
The MMU can be configured to use either small or large pages as well as sections
or supersections. Sections (or supersections) can be mixed together with pages.
Just because the architecture supports mapping blocks of several different sizes
does not mean that the operating system will use the capability. Doing so
introduces the problems associated with variable size partitions that we discussed
earlier. However, even if this is not used for general-purpose memory
management, it makes a lot of sense for mapping the operating system address
space efficiently Translation Lookaside Buffers (TLB)
The ARM has two levels of TLBs. The smallest and fastest is the MicroTLB. There is a
MicroTLB for the instruction and data sides of the CPU (instruction fetches uses one
MicroTLB while data read/write operations use the other). The MicroTLB can store 32 entries
[2]. The cache is fully associative and can perform a lookup in one clock cycle. Hence, there is
no performance penalty for any memory references that are satisfied by the MicroTLB. The
architecture supports the use of an address space identifier (ASID) to allow the operating
system to identify one process' address space from another's without flushing the cache. Entries
can also be tagged as global; so that they are shared among all address spaces. This is, of
course, useful for mapping the memory regions used by the operating system. Each entry
contains a number of protection bits and these are checked at each address lookup. If the
protections disallow the requested memory operation (e.g., no-execute or read-only) then the
MMU will signal a Data Abort, which will cause a trap. On a cache miss, the replacement
algorithm may be selected to be either round-robin (the default) or a random replacement.
The second-level TLB is called the Main TLB. It catches any cache misses from the
microTLBs. There is only one of these per processor, so it handles misses from both the
dataside and instruction-side MicroTLBs. The cache comprises eight fully associative entries,
which are fast and may also have their contents locked (i.e., they will not be replaced). It also
The operating system, in addition to locking the TLB entries, has to ensure that the
corresponding page frames stay locked in memory as well.
Figure 2 illustrates the full set elements that come into play for memory translation:
1. The first step is a MicroTLB lookup. An instruction fetch accesses the Instruction
MicroTLB and a data read/write operation accesses the Data MicroTLB. If this lookup
yields a match then the access permission in the page table entry are validated. If the
request does not have proper permissions then a trap is generated (Data Abort signal).
Otherwise, the memory access takes place. If the lookup yields no match then we
continue to step 2.
2. If the MicroTLB lookup yielded a cache miss then we consult the Main TLB. The process
is the same as with the MicroTLB. If there is a match for the requested page and the
permissions pass then the memory access is performed. If the lookup yields no match
then we continue to step 2.
The IA-32 architecture supports a combined segmentation and paging model (figure 2).
There are two tables of segments. Each contains base addresses of up to 8,191 segments. the
Local Descriptor Table (LDT) contains segment information that is private per process. The
Global Descriptor Table (GDT) contains segment information that is shared among all
processes (e.g., segments into the operating system). The segment selector, which comprises 16
bits of a "far pointer", is an index into these tables. To select a segment, the selector is loaded
into a segment register. Also, every instruction that references memory has an implicit segment
register, which can be overridden by adding a segment prefix before the machine instruction.
The value of the segment selector automatically selects the GDT (shared) or LDT (private).
This combined model uses segmentation to generate a linear address. This linear address is
then treated as a virtual address and is translated by the paging logic of the MMU through a
two-level page table hierarchy.
The paging logic can be disabled if it is not needed. If segment descriptors contain 0, they
effectively set the base address of a segment to 0, making every memory reference a linear one.
Thus, you can effectively use either paging or segmentation or both.
IA32 segmentation
Each entry in the GDT contains not just the base address of a segment but also a number of
flags that define segment attributes:
S flag: Is this a code or data segment?
Accessed: Has the segment been accessed since the last time the OS cleared this bit?
Dirty: Has the page been modified since the last time the OS cleared this bit?
Data/write-enable: Is the segment read-only or read/write?
Data/expansion direction: Normally, changing the segment limit (size) causes
space to be added to the top of the segment. This changes the expansion direction
downward, causing space to be added at the bottom of memory. This was designed for
stacks.
Code/execute-only or execute/read: If this is a code segment, can the memory be
read as data or just executed?
Conforming: If the code is tagged as conforming then execution can continue even if
the privilege level is elevated.
IA32 paging
The paging logic uses a 32-bit logical address space to create either a 52-bit or a 36-bit physical
address, addressing up to either 4 petabytes or 4 gigabytes of memory. 52-bit addressing is
enabled via the Physical Address Extension (PAE) mechanism. However, a process can access
only a 4 GB address space at any time. The 36-bit address space is enabled via the Page Size
Extension (PSE-36). The paging architecture supports 4 KB or 4 MB pages.
* * *
PAE
The PAE mode emulates the Physical Address Extension mode of the IA-32 architecture. It
uses 32-bit virtual
addresses and
generates up to
52bit physical
addresses using
either 4 KB or 2 MB
pages.
With 4 KB
pages (figure 6), the
Figure 6. PAE Paging
with 4 KB pages
MMU uses a three-
level page table
hierarchy is used to
map a 32-bit virtual address to a 52-bit physical address. The topmost table is a 4-entry page
directory pointer table (PDPT) that is indexed by the top two bits of the virtual address.
An entry in the PDPT points to a partial page directory that is indexed by the next 9 bits (512
entries per partial page directory). The page directory points to a partial page table, which is
indexed by the next 9 bits (also 512 entries per partial page table). A PTE contains the top 40
bits of the physical address. The bottom 12 bits are the obtained directly from the linear
address and are the offset into a 4 KB page frame.
* * *
IA-32e paging
By increasing the page size to 2MB, we reduce the number of pages the system needs to
manage by a factor of 512. This allows the MMU to use one less Figure 8. IA32e Paging with 2
MB pages level of hierarchy in the page table structure (figure 8). With 2 MB pages, three
levels of the hierarchy are used.By further increasing the page size to a whopping 1 GB, the
page table is reduced to a twolevel hierarchy with a 512entry table containing base addresse
of 512-entry partial page tables (figure 9).
Translation Lookaside Buffers (TLBs)
The structure of the TLB is similar across Intel processors, but the sizes of the caches differ. Let's take the Intel Core i7
as an example. Like the ARM MMU, the TLB has two levels. Each core's instruction and data pages maintain a TLB
containing 128 entries for instructions and 64 entries for data. It is super fast, fully associative, and allows same-cycle
main memory accesses. The second level TLB is much faster than moving to main memory, is consolidated across
cores, and contains 512 page table entries.
Demand paging
It’s not uncommon for the virtual address space to be bigger than the physical
address space. A process typically uses only a small fraction of the virtual
address space and the operating system needs to map only the parts that are
used into physical memory (page frames). What if this isn’t the case? What if a
process needs to use more memory than is available on the system? Or, since we
have a multitasking environment where we time slice execution among multiple
processes, what if the memory requirements of all of our processes are greater
than the physical memory on the system? In this case, we will have to save some
pages onto the disk and bring them back later when we need them.
Demand paging is an approach to memory management where we load pages into
memory only as they are needed by the process.
The valid/invalid bit in a page table entry (PTE) tells the memory management unit whether a
specfic page is mapped into physical memory ("valid") or is not ("invalid"). An attempt to acces
an invalid page will cause the MMU to generate a page fault. If a page is not mapped to
memory, that means that it is either an invalid (unallocated, out-of-bounds) region of the
process' address space or that it is a valid region that is not currently resident in main memory.
The operating system has to determine which one of these cases holds. The page fault handler
performs the following actions:
1. Check the memory map in the process control block for that process to see if the memory
access was indeed valid (versus out of bounds or dereferencing a null pointer)
New stack and heap pages have no contents will not require reading
contents from the disk.
If the page maps to an existing stack or heap region and was saved onto
the disk in the past because we didn't have enough pages, it will be read from a page
file on the disk.
6. Context switch, since we need to wait for the contents to be read. This, of course is not
needed for newly-allocated pages.
7. When the disk read is complete, modify page table for the process. The page table entry
will now be flagged as valid and will contain the address of the page frame into which we
read the page.
Page replacement
1. Ideally, the operating system would have many unused page frames, and the page fault
handler would pick one of them, load the page, and map it into the requesting process's
page table. What if all the page frames are in use by the process? In this case, we need to
replace the pages in memory with the pages on disk. The order of operations is as
follows:Pick a page to evict.
2. Save the contents of the page onto the paging file on the disk if the page has been
modified (the dirty bit in the page table entry is set). If the page has not been modified
(e.g., it's a static data or code page) then we can always re-read it from the program file.
3. Change the page table for the process whose page we evicted to show that the
corresponding page is no longer valid.
What we don't want to do is evict a page that is likely to be used again because then we'll have to
go through the same sequence of operations just to get it back. We need a good page
replacement policy to ensure that we can still maintain good performance. Let's examine a few
replacement policies.
References
(http://www.intel.com/products/processor/manuals/)
(http://www.intel.com/products/processor/manuals/)