By the comments in source code, deallocate does deallocating user pages to bring the process size from oldsz to newsz
My question is when pte not existed, it should continue searching next page directory entry, but why PGADDR(PDX(a) + 1, 0, 0) should minus PGSIZE here.
if(!pte)
a = PGADDR(PDX(a) + 1, 0, 0) - PGSIZE;
Here is the source code from 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;
}