modify uvmunmap() to be in aligned pages
fix a bug in fork() recovering from out of memory
This commit is contained in:
		
							parent
							
								
									e1a2cd59fa
								
							
						
					
					
						commit
						70c6fe861e
					
				
					 2 changed files with 18 additions and 21 deletions
				
			
		| 
						 | 
					@ -175,8 +175,8 @@ proc_pagetable(struct proc *p)
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
proc_freepagetable(pagetable_t pagetable, uint64 sz)
 | 
					proc_freepagetable(pagetable_t pagetable, uint64 sz)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uvmunmap(pagetable, TRAMPOLINE, PGSIZE, 0);
 | 
					  uvmunmap(pagetable, TRAMPOLINE, 1, 0);
 | 
				
			||||||
  uvmunmap(pagetable, TRAPFRAME, PGSIZE, 0);
 | 
					  uvmunmap(pagetable, TRAPFRAME, 1, 0);
 | 
				
			||||||
  uvmfree(pagetable, sz);
 | 
					  uvmfree(pagetable, sz);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								kernel/vm.c
									
										
									
									
									
								
							
							
						
						
									
										35
									
								
								kernel/vm.c
									
										
									
									
									
								
							| 
						 | 
					@ -167,24 +167,23 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Remove mappings from a page table. The mappings in
 | 
					// Remove npages of mappings starting from va. va must be
 | 
				
			||||||
// the given range must exist. Optionally free the
 | 
					// page-aligned. The mappings must exist.
 | 
				
			||||||
// physical memory.
 | 
					// Optionally free the physical memory.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
uvmunmap(pagetable_t pagetable, uint64 va, uint64 size, int do_free)
 | 
					uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  uint64 a, last;
 | 
					  uint64 a;
 | 
				
			||||||
  pte_t *pte;
 | 
					  pte_t *pte;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  a = PGROUNDDOWN(va);
 | 
					  if((va % PGSIZE) != 0)
 | 
				
			||||||
  last = PGROUNDDOWN(va + size - 1);
 | 
					    panic("uvmunmap: not aligned");
 | 
				
			||||||
  for(;;){
 | 
					
 | 
				
			||||||
 | 
					  for(a = va; a < va + npages*PGSIZE; a += PGSIZE){
 | 
				
			||||||
    if((pte = walk(pagetable, a, 0)) == 0)
 | 
					    if((pte = walk(pagetable, a, 0)) == 0)
 | 
				
			||||||
      panic("uvmunmap: walk");
 | 
					      panic("uvmunmap: walk");
 | 
				
			||||||
    if((*pte & PTE_V) == 0){
 | 
					    if((*pte & PTE_V) == 0)
 | 
				
			||||||
      printf("va=%p pte=%p\n", a, *pte);
 | 
					 | 
				
			||||||
      panic("uvmunmap: not mapped");
 | 
					      panic("uvmunmap: not mapped");
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if(PTE_FLAGS(*pte) == PTE_V)
 | 
					    if(PTE_FLAGS(*pte) == PTE_V)
 | 
				
			||||||
      panic("uvmunmap: not a leaf");
 | 
					      panic("uvmunmap: not a leaf");
 | 
				
			||||||
    if(do_free){
 | 
					    if(do_free){
 | 
				
			||||||
| 
						 | 
					@ -192,9 +191,6 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 size, int do_free)
 | 
				
			||||||
      kfree((void*)pa);
 | 
					      kfree((void*)pa);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *pte = 0;
 | 
					    *pte = 0;
 | 
				
			||||||
    if(a == last)
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    a += PGSIZE;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -265,9 +261,10 @@ uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
 | 
				
			||||||
  if(newsz >= oldsz)
 | 
					  if(newsz >= oldsz)
 | 
				
			||||||
    return oldsz;
 | 
					    return oldsz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uint64 newup = PGROUNDUP(newsz);
 | 
					  if(PGROUNDUP(newsz) < PGROUNDUP(oldsz)){
 | 
				
			||||||
  if(newup < PGROUNDUP(oldsz))
 | 
					    int npages = (PGROUNDUP(oldsz) - PGROUNDUP(newsz)) / PGSIZE;
 | 
				
			||||||
    uvmunmap(pagetable, newup, oldsz - newup, 1);
 | 
					    uvmunmap(pagetable, PGROUNDUP(newsz), npages, 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return newsz;
 | 
					  return newsz;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -298,7 +295,7 @@ void
 | 
				
			||||||
uvmfree(pagetable_t pagetable, uint64 sz)
 | 
					uvmfree(pagetable_t pagetable, uint64 sz)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if(sz > 0)
 | 
					  if(sz > 0)
 | 
				
			||||||
    uvmunmap(pagetable, 0, sz, 1);
 | 
					    uvmunmap(pagetable, 0, PGROUNDUP(sz)/PGSIZE, 1);
 | 
				
			||||||
  freewalk(pagetable);
 | 
					  freewalk(pagetable);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,7 +331,7 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 err:
 | 
					 err:
 | 
				
			||||||
  uvmunmap(new, 0, i, 1);
 | 
					  uvmunmap(new, 0, i / PGSIZE, 1);
 | 
				
			||||||
  return -1;
 | 
					  return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue