Page Tables

IMPLEMENTATION OF SWAPPING IN VIRTUAL MEMORY

Each address space within the system has associated with it a page table and a disk map. Each of these two tables describe an *entire* address space. The page table identifies which pages are in main memory, and in which page frames those pages are located. The disk map identifies where all the pages are on the disk. The entire address space is on the disk, but only a subset of it is resident in main memory.


(Note: additional flags may also be present, but these are the significant ones.)

If the P flag in the page table is set, the page is currently in main memory. Its location in memory is determined by the F value; F is the number of the page frame in which the page is located. If the P flag is clear, the address mapper will generate a page fault if a process attempts reference to the page; the page fault handler will use the disk map to locate that page on the disk and swap it in. Each address space must have a complete mapping on disk (i.e. the entire addess space must be available on disk). In the event that a process is swapped out entirely, none of its address space will be in main memory; all of it will be in secondary storage. The set of pages shown in the page table as present are a subset of the pages on the disk. Those with the M flags set are not exact copies any more and must be copied back to disk before they can be deleted from main memory. It is possible to combine the page table and disk map by adding the disk address field to the page table:



But this is generally not done because it makes the page table bigger and may slow down address translation. An address space on disk is implemented as a file. A file of the address space's size is created and identified as a virtual memory:

d = CREATE_VM(file)

The Create Virtual Memory routine creates the necessary support structures for the space and returns a pointer, d, that identifies the virtual memory. Thus, a process having virtual memory d would use page table PT[d] and disk map DM[d]. When the process exits, the operating system must remove the address space from disk and the page table using the command

DELETE_VM(d)

Address space id's and process id's are not synonymous. Several threads (different process id's) can be operating in the same address space (same address space id); they all use the same page table and disk map.

When a page is to be swapped in, the system locates a candidate frame from the list of page frames. Normally, the least-recently-used (LRU) frame is considered to best candidate. The frame number is used as an index into yet another table the system maintains: the frame table. The frame table describes how the main memory is being used; thus, there is only one frame table for the entire system. Within the frame table, there is one slot for each page frame in main memory. Each slot identifies the address space (d, from above) using the frame and the page, x, of that address space within the frame.

(d,x) = FRAMES(y)

y = PT(d,x)


Note that the frame number, F, from the page table points to a frame in main memory. The disk address A in the disk map points to a disk sector that contains the page in the on-disk copy of the virtual memory.

When a page fault occurs, the page fault handler procedure is invoked in the address space of the faulting process. It's overall job is: "make the missing page present". When it returns, the faulting process retries the addressing operation that just failed; now it will succeed.

The job "make the missing page present" consists of these steps:

1) Using the replacement algorithm, get the number of a frame that will be used for the incoming page: y = REPLACE.

2) Swap the page currently in frame y to its slot on the disk; that slot is DM[FRAMES[y]].

3) Swap the requested page x from its slot on the disk into frame y; that slot is DM[d,x].

4) Update the page table entry PT[d,x] so that P=1 and F=y, and update FRAMES[y] to (d,x).
5) Return.

Steps 2 and 3 involve an interaction with the disk driver. The protocol for this has been described previously. When the step is started, it will not complete until the disk has sent back its completion interrupt signal. Since these steps involve swapping, it is worthwhile to eliminate one or both of them whenever possible.

Step two may be skipped if the identified page frame has not been modified (written to) since it was loaded or last written to disk. As a result, when identifying candidate frames, the system will give preference to unmodified pages.

Step three can be eliminated in case the requested page is still loaded in main memory. This can happen if the replacement algorithm marks the page as not present, but the owner process refers to it again before it is swapped out. The test for this is that PR[d,x].F = y and FRAMES[y] = (d,x).

In step five, the processor is returned to the state in which it was running when the page fault occured. Often, this is not a trivial task. Refer to Tannenbaum [T1] for a superficial discussion on the issues involved.

In order to facilitate the above actions and make the likelihood of unneeded swaps as low as possible, the main memory page frames can be divided into four groups by the combination of their (P,M) bits. The (0,0) frames are called the "pool" of frames ready to be used to satisfy page faults. The replacement algorithm is instantiated as a background process that watches for unused frames and marks them as P=0; if a newly marked page has M=1 (frame state is (0,1)), a request to copy it out to disk is queued up; when that request is complete the frame is moved to the (0,0) state. With this structure, the first step of "make page present" is simply to take the first frame from the list of (0,0) frames. (That list must be semaphore protected so that the caller waits until there is at least one frame in the (0,0) state, a condition that is guaranteed because the replacement policy is working in the background to guarantee that there are (0,0) pages.) [D7]

--P.J. Denning and Steve Coile

Also see [D1] pp. 157-159 and [T1] pp.89-96.