Mit6.828 HW4:xv6 lazy page allocation

HW4: xv6 lazy page allocation的做题思路,以及答案。

概述

所谓lazy allocation,就是内存的延迟分配。应用程序在申请内存的时候,内核通过stbrk系统调用给它分配了内存,但是并未将这些虚拟地址映射到实际地址,直到应用程序使用到了该部分地址的时候,触发了缺页错误,此时,内核才会真正地分配物理内存。

Part One: Eliminate allocation from sbrk()

修改代码如下:

diff --git a/sysproc.c b/sysproc.c
index 0686d29..ef36495 100644
--- a/sysproc.c
+++ b/sysproc.c
@@ -51,9 +51,10 @@ sys_sbrk(void)
   if(argint(0, &n) < 0)
     return -1;
   addr = myproc()->sz;
-  if(growproc(n) < 0)
-    return -1;
-  return addr;
+  //if(growproc(n) < 0)
+    //return -1;
+  myproc()->sz = addr + n;
+  return addr;
 }

测试结果如下,触发了14的中断。

Part Two: Lazy allocation

Modify the code in trap.c to respond to a page fault from user space by mapping a newly-allocated page of physical memory at the faulting address, and then returning back to user space to let the process continue executing. 

  1. 页故障的中断号为14,从告警pid 3 sh: trap 14 err 6 on cpu 0 eip 0x112c addr 0xc004--kill proc可以看出,traps.h的注释也说明了#define T_PGFLT         14      // page fault
  2. 我们需要照抄allocuvm的流程,而不是直接调用它,因为allocuvm中调用的是PGROUNDUP宏,而不是PGROUNDDOWN宏,会导致我们映射的地址并不会涵盖页面故障的地址。
  3. 寄存器cr2中保存的是出现页故障的时候,32位线性地址。
  case T_PGFLT:
    {
      struct proc *curproc = myproc();
      //获取页故障的虚拟地址
      uint va_start = rcr2();
      uint a = PGROUNDDOWN(va_start);
      char *mem = kalloc();
      if(mem == 0){
        cprintf("allocuvm out of memory\n");
        return;
      }
      memset(mem, 0, PGSIZE);
      if(mappages(curproc->pgdir, (char*)a, PGSIZE, V2P(mem), PTE_W|PTE_U) < 0){
        cprintf("allocuvm out of memory (2)\n");
        kfree(mem);
        return;
      }
    }
    break;

optional challenge等以后有空再做

Tags: Mit6.828
Share: X (Twitter) Facebook LinkedIn