4 ms·
Does anyone know how to extend xv6 with copy-on-write? I was implementing a multiprocessing lib based on xv6 but noticed a fork copied the entire parent page ta
by shawn 8y ago
Does anyone know how to extend xv6 with copy-on-write? I was implementing a multiprocessing lib based on xv6 but noticed a fork copied the entire parent page table.
I think it’s a matter of extending the page fault routine to check whether the missing page is flagged copy on write, but I wasn’t sure how to correctly track which source page it should be copied from. Every process has its own clone of the page table hierarchy, so how do you know which one to grab during the fault?
- mav3rick 8y agoWhen you fork, your forked process get a copy of the parent's page table i.e. at this point it points to the same physical page for xyz address as the parent. There can be a metadata bit in the final PTE that says this page is COW (Copy on Write). For context, in a 32-bit system 2 Level page table with 4KB pages means only 20 bits are used in the final page table to get the page frame. There are 12 bits free for some metadata. Your forked process already has the physical page frame number and the COW bit. If it's a write/modify on that page and the COW is set, your code should allocate a new physical page, copy the raw contents of the currently mapped physical page and then finally update the page table entry with this new physical page frame number. If you want an example with some numbers, I can reply further. Let me know :)
- shawn 8y agoThanks! This was very helpful. If you want an example with some numbers, I can reply further. I appreciate that. I learn best from working models. But in this case, the solution after you pointed it out is extremely obvious: if the COW bit is set, unset it and alloc+copy the page. No other information is needed. Perhaps you know of a similarly elegant solution to the other half of what I’ve been struggling with: xv6 is 32 bit, and gives little insight on how to do paging on a 64 bit architecture. So I have two questions. 1. I notice that although pages are 4KB, xv6 uses 4MB (large paging support). How does this impact the two-level page table design? Does it simply mean that fewer entries are required, but the design is unchanged? 2. On a 64 bit architecture, what are the fundamental differences between the 2 level page table design and whatever people do in practice? This is phrased poorly. What I mean is: I am trying to blindly extend xv6’s design for a 64bit environment, but I am concerned the design might need to change. Is that true, or do people do the same thing on 64 bit? I haven’t had time to think this through yet. To put it more simply, is there anything I should watch out for on 64 bit when doing this? Or perhaps some overall simplification / better design for 64 bit that can’t be done on 32 bit? These are mostly speculative questions, so perhaps I should wait until I’m stuck before asking. But your answer was insightful. I’m trying to make something people will use, and xv6 has been my only model to learn from. Any advice or references about 64 bit design for multiprocess scheduling would be useful. Especially in contexts where performance and parallelism is the concern, not necessarily security. (Anything to do with GPU design would be a delightful bonus. But I do still need traditional function calls + lexical closures.)