Nachos Project 3: Implement Demand Paging - Operating Systems | COMP 310, Study Guides, Projects, Research of Operating Systems

Material Type: Project; Class: Operating Systems; Subject: Computer Science; University: University of San Diego; Term: Unknown 1989;

Typology: Study Guides, Projects, Research

Pre 2010

Uploaded on 08/18/2009

koofers-user-3sx-2
koofers-user-3sx-2 🇺🇸

10 documents

1 / 6

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
COMP310: Nachos Project #3: Implement Demand Paging1
First part due: Wednesday, Nov 24, 1:15pm
Remaining parts due: Monday, Dec 13, 1:15pm
IMPORTANT! Before you begin this assignment, make a complete copy of your entire nachos direc-
tory from project 2. DO NOT CHANGE ANY CODE IN THE ORIGINAL DIRECTORIES (i.e. the
directories your project 2 writeup pointed me to). DO ALL YOUR PROJECT 3 WORK IN THE
NEWLY COPIED FILES.
In this project you will extend Nachos to support demand paged virtual memory. This new functionality
gives processes the illusion of a virtual memory that is larger than the available machine memory.
You will implement and debug virtual memory in two steps. First, you will implement demand paging using
page faults to allocate page frames to processes on demand, only when a process tries to access a VP that
does not yet have a corresponding physical page. In other words, this scheme differs from what you did in
project 2 in the following way. In project 2 when a new process was launched, you allocated, initialized and
loaded all of the pages that the process required, including the code, the data, the stack and the argument
space. Only once all pages were allocated, initialized and loaded did you allow your process to run. In
contrast, in this project, you will not allocate these pages up front, but instead only allocate and load a
physical page when the process needs it because it refers to a new page of VM that has not yet been loaded
(this might occur when the process tries to read code, data, arguments, etc).
Second, you will implement page replacement, enabling your kernel to evict a virtual page from memory in
order to free up a physical page frame to satisfy a page fault. Above, we were still assuming that all pages
fit into physical memory. For this second part, you will lift that assumption, writing pages to disk when they
must be evicted from memory, and reading them back in when a process tries to access them.
Demand paging and page replacement together allow your kernel to ”overbook” memory by executing more
processes than would fit in machine memory at any one time, using page faults to ”juggle” the available
physical page frames among the larger number of process virtual pages. If it is implemented correctly,
virtual memory is undetectable to user programs unless they monitor their own performance.
The operating system kernel works together with the machine’s memory management unit (MMU) (which
contains, among other things, the TLB, which you will not have to implement for this assignment) to support
virtual memory. Coordination between the hardware and software centers on the page table structure for each
process. You used page tables in Project 2 to allow your kernel to assign any free page frame to any process
page, while preserving the illusion of a contiguous memory for the process. The indirect memory addressing
through page tables also isolates each process from bugs in other processes that are running concurrently.
We have talked a lot in class about the other components in the page table entry (PTE), and you may have
noticed that the PTEs in nachos had a number of other fields that you did not use in project two. In this
project, you will use the following additional bits in the PTE:
1As in project 2, this project write-up is based on a modified and more detailed version or the original nachos project 3, created
by Prof. Geoff Voelker at UCSD
1
pf3
pf4
pf5

Partial preview of the text

Download Nachos Project 3: Implement Demand Paging - Operating Systems | COMP 310 and more Study Guides, Projects, Research Operating Systems in PDF only on Docsity!

COMP310: Nachos Project #3: Implement Demand Paging^1

First part due: Wednesday, Nov 24, 1:15pm

Remaining parts due: Monday, Dec 13, 1:15pm

IMPORTANT! Before you begin this assignment, make a complete copy of your entire nachos direc- tory from project 2. DO NOT CHANGE ANY CODE IN THE ORIGINAL DIRECTORIES (i.e. the directories your project 2 writeup pointed me to). DO ALL YOUR PROJECT 3 WORK IN THE NEWLY COPIED FILES.

In this project you will extend Nachos to support demand paged virtual memory. This new functionality gives processes the illusion of a virtual memory that is larger than the available machine memory.

You will implement and debug virtual memory in two steps. First, you will implement demand paging using page faults to allocate page frames to processes on demand, only when a process tries to access a VP that does not yet have a corresponding physical page. In other words, this scheme differs from what you did in project 2 in the following way. In project 2 when a new process was launched, you allocated, initialized and loaded all of the pages that the process required, including the code, the data, the stack and the argument space. Only once all pages were allocated, initialized and loaded did you allow your process to run. In contrast, in this project, you will not allocate these pages up front, but instead only allocate and load a physical page when the process needs it because it refers to a new page of VM that has not yet been loaded (this might occur when the process tries to read code, data, arguments, etc).

Second, you will implement page replacement, enabling your kernel to evict a virtual page from memory in order to free up a physical page frame to satisfy a page fault. Above, we were still assuming that all pages fit into physical memory. For this second part, you will lift that assumption, writing pages to disk when they must be evicted from memory, and reading them back in when a process tries to access them.

Demand paging and page replacement together allow your kernel to ”overbook” memory by executing more processes than would fit in machine memory at any one time, using page faults to ”juggle” the available physical page frames among the larger number of process virtual pages. If it is implemented correctly, virtual memory is undetectable to user programs unless they monitor their own performance.

The operating system kernel works together with the machine’s memory management unit (MMU) (which contains, among other things, the TLB, which you will not have to implement for this assignment) to support virtual memory. Coordination between the hardware and software centers on the page table structure for each process. You used page tables in Project 2 to allow your kernel to assign any free page frame to any process page, while preserving the illusion of a contiguous memory for the process. The indirect memory addressing through page tables also isolates each process from bugs in other processes that are running concurrently. We have talked a lot in class about the other components in the page table entry (PTE), and you may have noticed that the PTEs in nachos had a number of other fields that you did not use in project two. In this project, you will use the following additional bits in the PTE:

(^1) As in project 2, this project write-up is based on a modified and more detailed version or the original nachos project 3, created by Prof. Geoff Voelker at UCSD

  • Valid bit: The kernel sets or clears the valid bit in each PTE to tell the machine which virtual pages are resident in memory (a valid translation) and which are not resident (an invalid translation). If a user process references an address for which the PTE is marked invalid, then the machine raises a page fault exception and transfers control to your kernel’s exception handler.
  • Use bit: The machine sets the use bit (aka reference bit) in the PTE to pass information to the kernel about page access patterns. If a virtual page is referenced by a process, the machine sets the corre- sponding PTE reference bit to inform the kernel that the page is active. Once set, the reference bit remains set until the kernel clears it.
  • Dirty bit: The machine sets the dirty bit in the PTE whenever a process executes a store (write) to the corresponding virtual page. This informs the kernel that the page is dirty; if the kernel evicts the page from memory, then it must first ”clean” the page by writing its contents to disk. Once set, the dirty bit remains set until the kernel clears it.

This project has four parts. You should complete as much of Part 1 by the first due date. Points for part 1 will be allocated as follows: 15 of the 35 points will be based on the completeness and correctness of what you turn in before thanksgiving (focusing on the correctness of your writeup of what you have done, more than on the code. Even if your code is incomplete, it’s still possible to get almost all of the 15 points for this part). The remaining 20 points will be based on what you turn in after by the final deadline.

  1. (35 pts) Implement demand paging (i.e., don’t initialize/load a PF for a VP until the process tries to access it). In the first part, you will continue to preallocate a page frame for each virtual page of each newly created process at Exec time, just as in Project As before, return an error from the Exec system call if there are not enough free page frames to hold the process’ new address space. But for this part, you need to make the following changes to AddrSpace:

(a) In your AddrSpace initialization method, initialize all the PTEs as invalid. (b) In the same method, remove the code that (1) zeros out the physical page frames, and (2) preloads the address space with the code and data segments from the file. You will do this on demand when the process causes a page fault – for now, you will continue to allocate physical page frames in AddrSpace for each virtual page, but delay loading the frames with data until they are actually referenced by the process. (c) Handle page fault exceptions in ExceptionHandler. When the process references an invalid page, the machine automatically will raise a page fault exception (if a page is marked valid, no fault is generated). You do not have to do anything to get the page faults to occur (other than mark the pages as invalid). You simply have to handle the exception when it happens. Modify your exception handler to catch this exception and handle it by preparing the requested page on demand (see next step). (d) To prepare the requested page on demand, add a method to AddrSpace to page in the faulted page from the executable file. Note that faults on different address space segments are handled in different ways. For example, a fault on a code page should read the corresponding code from the executable file, a fault on a data page should read the corresponding data from the executable file, and a fault on a stack page or argument page should zero-fill the frame.

(b) Evict the victim page. If the page is clean (i.e., not dirty), then the page can be used immediately; you can always recover the contents of the page from disk. If the page is dirty, though, the kernel must save the page contents in backing store on disk. (c) Read in the contents of the faulted page either from the executable file or from backing store (see below). (d) Implement a BackingStore class to handle page in and page out operations. An important part of this project is to use the Nachos file system interface to allocate and manage the backing store. Implement methods to allocate space on backing store, locate pages on backing store, push pages from memory to backing store (for page out), and pull from backing store to memory (for page in). (e) Use the FileSystem class to create files for backing store (see filesys/filesys.h). After creating the backing store file, use the FileSystem class to open it. Opening the file will return an OpenFile object, which allows you to do reads and writes (see filesys/openfile.h). The Makefiles are setup to compile with FILESYS STUB defined, so be sure to look at that version of the classes.

As you implement the above operations, keep the following points in mind:

  • As in the first part of the project, the first time a page is touched it needs to be initialized (from the executable file for code and data, bzero’d otherwise; see part 1 above). If this page is subsequently evicted to backing store, it will be read from there on further page faults.
  • You are not limited to one file for backing store for the entire system, and might find it more convenient to have a backing store file for each process (doing so makes locating evicted pages convenient).
  • Be sure to clear the dirty bit when you mark a PTE for the victim page as invalid.
  • When running multiple processes, you may select a victim page from another process. As a result, you will need to update the PTE in the page table for that process, not the faulting one.
  • You may use any page replacement strategy discussed in the book or in class. I recommend you start with a simple one, such as random replacement or FIFO. For extra credit, you may implement LRU (see below).

Finally, you should only do as many page reads and writes as necessary to execute the program, and as dictated by your page replacement algorithm. You will soon discover that the first page fault is different than subsequent ones on code and data pages. On the first fault you need to read from the executable file, and on the second you need to read from the backing store. Your implementation needs to be able to handle this situation. (Hint: you will need to use a data structure to keep track of whether or not this page has been read in previously... remember your table class?) It might be tempting to just copy the pages from the executable file to the backing store when the process is first created, or on a page-by-page basis when the first fault occurs, but both of these cases introduce extra unecessary disk I/Os and should not be used.

  1. (15 pts) Testing. In this project, programs can use more virtual memory than physical memory, and pages are brought into memory only if they are actually referenced by the user program. To show that you only initialize pages that are referenced on demand, write one test program that references all of the pages in memory, and a second test program that only references some of the pages. You can use the pagein and pageout counters (below) to convince yourself that you are only initializing the pages that are referenced by the process. For example, accessing a two-dimensional array selectively (e.g., all rows, some rows) can give different page reference behavior, and not calling a function will only

execute a subset of the code in an executable file. We do not particularly care if the test programs do anything useful (like multiplying matrices), but they should generate memory reference patterns of interest. Your test programs should also demonstrate the page replacement policy and correct handling of dirty pages (e.g., allocating backing storage and preserving the correct contents for each page on backing store). Implement additional test programs that (1) generate good locality (most references are to a small subset of pages), and (2) generate poor locality (everything is referenced repeatedly in a pattern), and (3) random locality (pages are effectively referenced randomly). If necessary, try reducing the amount of physical memory to ensure more page replacement activity. On the web site, I have included a link to an example test program that is larger than physical memory and uses the console to draw a ”snake” wandering around on the screen called snake.c. Feel free to use snake, matmult and sort (already in the test directory) to perform initial tests, but you must also write your own test programs.

  1. (15 pts) Maintain counters of page faults and pagein and pageout events. Print out these counters when Nachos exits. This will aid in debugging, and indicate how well the page replacement algorithm is working with the processes running in the system. You might also want to print out a DEBUG message when each of these events occurs as the process is running (and identify the process that caused the event so that you can disambiguate among multiple executing processes). In particular, add two new counters to the Statistics class in machine/stats.h, numPageOuts and numPageIns, and update the constructor and Print methods in stats.cc to initialize and report the values of those counters (ignore the top of the file where it says to not change the file). Increment the ”PageOut” counter whenever you write a page to the backing store (e.g., ”clean” pages should not cause a PageOut). Increment the ”PageIn” counter whenever you read a page from (1) the original executable file and (2) your backing store. Print the values of those counters on the same line as the numPageFaults counter. With backing store implemented, your operating system will use main memory as a cache over a slower and cheaper backing store. As with any caching system performance depends largely on the policy used to decide which pages are kept in memory and which to evict. As you know, we are not especially concerned about the performance of your Nachos implementations (simplicity and correct- ness are paramount), but in this case we want you to experiment with one of the page replacement policies discussed in class. For project 3, use a simple algorithm to implement page replacement such as FIFO or random replacement. For extra credit, you can implement LRU or an LRU approximation (see below). In any case, document your replacement algorithm choices in the project writeup. In your writeup (either in your README or in your TESTCASES file), create a table that reports the values of the paging counters for all of the test programs that you used to test your page replacement algorithm. If you implemented more than one replacement algorithm, report the values for all of the algorithms that you implemented. Here is an example:

Physical memory size: 32 pages. Page replacement policy: Random.

Program PageFaults PageOuts PageIns halt 3 0 2 matmult 112 45 74 sort 755 624 722 (more)