From 7241838b4cecefb32bad4698e748fc31d008d94d Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 20 Aug 2019 20:23:18 -0400 Subject: Move labs into 6.828 repo. The lab text isn't dependent on specific xv6 code. Lab submission instructions etc. are likely going to be more MIT 6.828 specific. --- labs/cow.html | 109 ---------------------------------------------------------- 1 file changed, 109 deletions(-) delete mode 100644 labs/cow.html (limited to 'labs/cow.html') 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 @@ - - -Lab: Copy-on-Write Fork for xv6 - - - - -

Lab: Copy-on-Write Fork for xv6

- -

-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. - -

The problem

- -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. - -

The solution

- -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. - -

-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. - -

-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. - -

The cow test program

- -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: - -
-$ cow
-simple: fork() failed
-$ 
-
- -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. - -

-When you are done, your kernel should be able to run both cow and -usertests. That is: - -

-$ cow
-simple: ok
-simple: ok
-three: zombie!
-ok
-three: zombie!
-ok
-three: zombie!
-ok
-file: ok
-ALL COW TESTS PASSED
-$ usertests
-...
-ALL TESTS PASSED
-$
-
- -

Hints

- -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. - -

-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. - - - -- cgit v1.2.3