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;
}
The for
loop does a += PGSIZE
. And it does that each and every time the loop iterates.
If PGSIZE
is not subtracted when going to the next PDE, then a
would be off by PGSIZE
elements the next iteration.