6.Lab five —— Lazy Page Allocation

首先先切换到lazy分支

git checkout lazy
make clean

Xv6应用程序使用sbrk()系统调用向内核请求堆内存。sbrk()分配物理内存并将其映射到进程的虚拟地址空间。内核为一个大请求分配和映射内存可能需要很长时间。为了提高效率,故采用懒分配的策略

Eliminate allocation from sbrk()

删除sbrk(n)系统调用中的页面分配代码(kernel/sysproc.c)

Lazy allocation

1.修改kernel/trap.c里面的usertrap()函数,根据r_scause()判断是否为页面错误,(p->sz代表进程的地址上限)然后分配物理内存并添加映射

2.修改kernel/vm.c中的uvmunmap()函数,lazy allacation中没有实际分配内存,那么解除映射关系的时候这部分内存也要略过

第一个continue而言,主要解决的问题是一二级页表中存在Lazy Alloction的pte还未建立映射关系,所以walk函数会返回0

对于第二个continue而言,解决的是第三级叶子层页表中,某个pte还未建立映射关系,虽然walk函数返回值不为0,但是该pte是无效的

Lazytests and Usertests

1.kernel/sysproc.c中处理sbrk()参数为负数的情况,两种情况:sz+n >0 以及sz + n < 0。后面这种情况直接return - 1即可

前面那种则参考growproc()函数,调用uvmdealloc()函数缩减内存

2.处理fork拷贝(kernel/proc.c)

fork调用了uvmcopy(kernel/vm.c)进行内存拷贝,但现在进行了懒分配所以就不需要了,更改uvmcopy函数

3.还需要注意懒分配带来的影响,系统调用处理会陷入内核,scause寄存器存储的值是8,如果此时传入的地址还没有实际分配,并且此时也没有途径走到页面错误(scause = 13或者15的分支)那么syscall执行就会失败

  • 系统调用流程:

    • 陷入内核–>usertrapr_scause()==8的分支–>syscall()–>回到用户空间

  • 页面错误流程:

    • 陷入内核–>usertrapr_scause()==13||r_scause()==15的分支–>分配内存–>回到用户空间

所以使用系统调用的时候必须要知道何时会使用这些地址避免出现错误,事实上,将地址传入系统调用后,会通过argaddr函数(kernel/syscall.c)从寄存器中读取,因此在这里添加物理内存分配的代码

测试

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值