diff options
Diffstat (limited to 'labs/cow.html')
-rw-r--r-- | labs/cow.html | 109 |
1 files changed, 0 insertions, 109 deletions
diff --git a/labs/cow.html b/labs/cow.html deleted file mode 100644 index 2cc18fa..0000000 --- a/labs/cow.html +++ /dev/null @@ -1,109 +0,0 @@ -<html> -<head> -<title>Lab: Copy-on-Write Fork for xv6</title> -<link rel="stylesheet" href="homework.css" type="text/css" /> -</head> -<body> - -<h1>Lab: Copy-on-Write Fork for xv6</h2> - -<p> -Your task is implement copy-on-write fork in the xv6 kernel. You are -done if your modified kernel executes both the cow and usertests -programs successfully. - -<h2>The problem</h2> - -The fork() system call in xv6 copies all of the parent process's -user-space memory into the child. If the parent is large, copying can -take a long time. In addition, the copies often waste memory; in many -cases neither the parent nor the child modifies a page, so that in -principle they could share the same physical memory. The inefficiency -is particularly clear if the child calls exec(), since then most of -the copied pages are thrown away without ever being used. Of course, -sometimes both child and parent modify memory at the same virtual -address after a fork(), so for some pages the copying is truly needed. - -<h2>The solution</h2> - -The goal of copy-on-write (COW) fork() is to defer allocating and -copying physical memory pages for the child until they are actually -needed, in the hope that they may never be needed. - -<p> -COW fork() creates just a pagetable for the child, with PTEs for user -memory pointing to the parent's physical pages. COW fork() marks all -the user PTEs in both parent and child as read-only. When either -process tries to write one of these COW pages, the CPU will force a -page fault. The kernel page-fault handler detects this case, allocates -a page of physical memory for the faulting process, copies the -original page into the new page, and modifies the relevant PTE in the -faulting process to refer to the new page, this time with the PTE -marked writeable. When the page fault handler returns, the user -process will be able to write its copy of the page. - -<p> -COW fork() makes freeing of the physical pages that implement user -memory a little trickier. A given physical page may be referred to by -multiple processes' page tables, and should be freed when the last -reference disappears. - -<h2>The cow test program</h2> - -To help you test your implementation, we've provided an xv6 program -called cow (source in user/cow.c). cow runs various tests, but -even the first will fail on unmodified xv6. Thus, initially, you -will see: - -<pre> -$ cow -simple: fork() failed -$ -</pre> - -The "simple" test allocates more than half of available physical -memory, and then fork()s. The fork fails because there is not enough -free physical memory to give the child a complete copy of the parent. - -<p> -When you are done, your kernel should be able to run both cow and -usertests. That is: - -<pre> -$ cow -simple: ok -simple: ok -three: zombie! -ok -three: zombie! -ok -three: zombie! -ok -file: ok -ALL COW TESTS PASSED -$ usertests -... -ALL TESTS PASSED -$ -</pre> - -<h2>Hints</h2> - -Here's one reasonable plan of attack. Modify uvmcopy() to map the -parent's physical pages into the child, instead of allocating new -pages, and clear PTE_W in the PTEs of both child and parent. -Modify usertrap() to recognize a page fault. When a page fault occurs -on a COW page, allocate a new page with kalloc(), copy the old page to -the new page, and install the new page in the PTE with PTE_W set. -Next, ensure that each physical page is freed when the last PTE -reference to it goes away (but not before!), perhaps by implementing -reference counts in kalloc.c. Finally, modify copyout() to use the -same scheme as page faults when it encounters a COW page. - -<p> -It may be useful to have a way to record, for each PTE, whether it is -a COW mapping. You can use the RSW (reserved for software) bits in -the RISC-V PTE for this. - -</body> -</html> |