Lazy Lab
One of the many neat tricks an O/S can play with page table hardware is lazy allocation of user-space heap memory. Xv6 applications ask the kernel for heap memory using the sbrk() system call. In the kernel we’ve given you, sbrk() allocates physical memory and maps it into the process’s virtual address space. It can take a long time for a kernel to allocate and map memory for a large request. Consider, for example, that a gigabyte consists of 262,144 4096-byte pages; that’s a huge number of allocations even if each is individually cheap. In addition, some programs allocate more memory than they actually use (e.g., to implement sparse arrays), or allocate memory well in advance of use. To allow sbrk() to complete more quickly in these cases, sophisticated kernels allocate user memory lazily. That is, sbrk() doesn’t allocate physical memory, but just remembers which user addresses are allocated and marks those addresses as invalid in the user page table. When the process first tries to use any given page of lazily-allocated memory, the CPU generates a page fault, which the kernel handles by allocating physical memory, zeroing it, and mapping it. You’ll add this lazy allocation feature to xv6 in this lab.
Eliminate allocation from sbrk()
- for the system call
sbrl
- the positive argument , we simply increase the size of the process ,which means grows the address space ,but mark the addresses not valid in the page table ,
- the negative argument , we directly use the function
growproc
,which actually callsuvmunmap
1 | uint64 |
Lazy allocation
On a page fault on these not allocated address , the kernel allocates new pa and map into the page table.
1 | else if (r_scause() == 15 || r_scause() == 13) |
Lazytests and Usertests
According to the hints!
- Handle negative sbrk() arguments.
- Kill a process if it page-faults on a virtual memory address higher than any allocated with sbrk().
- Handle the parent-to-child memory copy in fork() correctly.
- Handle the case in which a process passes a valid address from sbrk() to a system call such as read or write, but the memory for that address has not yet been allocated.
- Handle out-of-memory correctly: if kalloc() fails in the page fault handler, kill the current process.
- Handle faults on the invalid page below the user stack.
- The negative argument is a little tricky ,we directly call
growproc
- higher va or lower va will be invalid , the higher va is simple to find ,the lower va is under the stack which are the guard page and text and data
- In
fork
actually inuvmcopy
, for the not exist page and not valid mapping , we ignore ! - For the system call
read and write
, will happen “ page fault ” inwalkaddr
,but not go to theusertrap
,we need to handle it inwalkaddr
1 | uint64 |
.The course lab site :MIT 6.S081 Lazy Lab