6.S081 2020 lab5 lazy allocation 记录

在这个实验中,需要基于page fault机制,为xv6实现lazy allocation的功能。

lazy allocation要做的是就是当用户调用sbrk为进程申请增加内存空间时,不立刻为进程分配物理内存,而是等到用户第一次访问到某个没有被分配过的页面时,再为进程分配物理内存并建立映射。

要在xv6中实现这个功能,第一件要做的事就是修改sbrk系统调用的实现,sbrk基本只是调用了下growproc函数,所以修改growproc即可。

在这里插入图片描述
这里修改的仅仅是当n大于0的情况,由于现在是lazy allocation,所以不急着马上分配物理内存,而是简单的修改进程的sz大小。对于n小于0的情况不用做修改。

现在一个进程的所拥有的页面可能还没有被分配,在uvmunmap执行时会unmap到不存在的页。在未修改的xv6中(eager allocation)这是不应该发生的情况,会导致内核panic。但在lazy allocation情况下,这是可能发生的正常现象,所以需要修改uvunmap。把原来panic的地方改成continue。
在这里插入图片描述
用户在访问到未分配的页面是会发生page fault进入内核,我们需要在usertrap()中处理这一情况。从riscv手册可知,当scause寄存器的值等于13或15时,说明发生了page fault。
在这里插入图片描述
在这里插入图片描述

在处理page fault时,从stval寄存器获取到引发page fault的虚拟地址va。判断起是否是lazy allocation情景下的合法地址。如果va 大于等于 进程的地址或者 小于 进程的栈顶地址sp,都是不合法的。然后为进程分配物理页并建立映射即可。这里需要注意页面的权限不要忘了加上PTE_U(因为我们是在为用户进程分配页面),如果忘记的话进程会再次在该页面上触发page fault(因为没有访问权限),再次map同一虚拟地址所在页面为导致xv6内核panic: remap。

现在还需要考虑一种情形,在fork时,xv6内核会将父进程的页面复制给子进程。这些页面中有些页面很可能还没被分配,未修改的xv6版本中复制未分配的页会导致panic。所以需要修改uvmcopy函数,在遇到未分配的页面时跳过即可。
在这里插入图片描述
还有一种情形是,如果用户是通过系统调用(如write,read)访问一个未分配的页,那么此时不会在用户态发生page fault(因为实际执行访存指令的时候已经在内核态了)。我们需要在这种情形下为进程分配页面。最简单的方法就是修改argaddr函数。
在这里插入图片描述
当系统调用的参数是个地址va时,在内核中可以通过walkaddr知道va是否已经分配了物理内存。如果没有,则为其分配物理内存并建立映射。

到这里lab lazy就结束了。lazytests和usertests都能完美通过。
在这里插入图片描述

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值