根据源代码中的注释,deallocate会释放用户页面,以将进程大小从oldsz变为newsz
我的问题是当PTE不存在时,它应该继续搜索下一页目录条目,但是为什么PGADDR(PDX(A)+ 1, 0, 0)应该减去PGSIZE。

 if(!pte)
          a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE;

以下是Xv6的源代码:
int
deallocuvm(pde_t *pgdir, uint oldsz, uint newsz)
{
  pte_t *pte;
  uint a, pa;

  if(newsz >= oldsz)
    return oldsz;

  a = PGROUNDUP(newsz);
  for(; a  < oldsz; a += PGSIZE){
    pte = walkpgdir(pgdir, (char*)a, 0);
    // pte not exists to next page table dir
    // do not understand why should minus PGSIZE
    if(!pte)
      a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE;
    // pte exists
    else if((*pte & PTE_P) != 0){
      pa = PTE_ADDR(*pte);
      if(pa == 0)
        panic("kfree");
      char *v = P2V(pa);
      kfree(v);
      *pte = 0;
    }
  }
  return newsz;
}

最佳答案

for循环确实a += PGSIZE。每次循环迭代它都会这样做。
如果在进行下一次PDE时没有减去PGSIZE,那么a将在下一次迭代中被PGSIZE元素关闭。

10-07 16:28