Cleanup if allocuvm fails to alloc. Add a test.
This commit is contained in:
		
							parent
							
								
									5048762c7e
								
							
						
					
					
						commit
						dd645ef119
					
				
					 3 changed files with 40 additions and 3 deletions
				
			
		
							
								
								
									
										4
									
								
								README
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								README
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -20,8 +20,8 @@ The following people made contributions:
 | 
			
		|||
    Cliff Frey (MP)
 | 
			
		||||
    Xiao Yu (MP)
 | 
			
		||||
 | 
			
		||||
In addition, we are grateful for the patches submitted by Greg Price,
 | 
			
		||||
Yandong Mao, and Hitoshi Mitake.
 | 
			
		||||
In addition, we are grateful for the patches contributed by Greg
 | 
			
		||||
Price, Yandong Mao, and Hitoshi Mitake.
 | 
			
		||||
 | 
			
		||||
The code in the files that constitute xv6 is
 | 
			
		||||
Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								usertests.c
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								usertests.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -324,6 +324,7 @@ mem(void)
 | 
			
		|||
  void *m1, *m2;
 | 
			
		||||
  int pid, ppid;
 | 
			
		||||
 | 
			
		||||
  printf(1, "mem test\n");
 | 
			
		||||
  ppid = getpid();
 | 
			
		||||
  if((pid = fork()) == 0){
 | 
			
		||||
    m1 = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1332,6 +1333,41 @@ sbrktest(void)
 | 
			
		|||
    wait();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // if we run the system out of memory, does it clean up the last
 | 
			
		||||
  // failed allocation?
 | 
			
		||||
  sbrk(-(sbrk(0) - oldbrk));
 | 
			
		||||
  int pids[32];
 | 
			
		||||
  int fds[2];
 | 
			
		||||
  if(pipe(fds) != 0){
 | 
			
		||||
    printf(1, "pipe() failed\n");
 | 
			
		||||
    exit();
 | 
			
		||||
  }
 | 
			
		||||
  for (i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
 | 
			
		||||
    if ((pids[i] = fork()) == 0) {
 | 
			
		||||
      // allocate the full 640K
 | 
			
		||||
      sbrk((640 * 1024) - (uint)sbrk(0));
 | 
			
		||||
      write(fds[1], "x", 1);
 | 
			
		||||
      // sit around until killed
 | 
			
		||||
      while (1) sleep(1000);
 | 
			
		||||
    }
 | 
			
		||||
    char scratch;
 | 
			
		||||
    if (pids[i] != -1)
 | 
			
		||||
      read(fds[0], &scratch, 1);
 | 
			
		||||
  }
 | 
			
		||||
  // if those failed allocations freed up the pages they did allocate,
 | 
			
		||||
  // we'll be able to allocate here
 | 
			
		||||
  c = sbrk(4096);
 | 
			
		||||
  for (i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
 | 
			
		||||
    if (pids[i] == -1)
 | 
			
		||||
      continue;
 | 
			
		||||
    kill(pids[i]);
 | 
			
		||||
    wait();
 | 
			
		||||
  }
 | 
			
		||||
  if (c == (char*)0xffffffff) {
 | 
			
		||||
    printf(stdout, "failed sbrk leaked memory\n");
 | 
			
		||||
    exit();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(sbrk(0) > oldbrk)
 | 
			
		||||
    sbrk(-(sbrk(0) - oldbrk));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								vm.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -195,7 +195,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
 | 
			
		|||
    if(pte == 0 || (*pte & PTE_P) == 0){
 | 
			
		||||
      char *mem = kalloc();
 | 
			
		||||
      if(mem == 0){
 | 
			
		||||
        // XXX clean up?
 | 
			
		||||
        cprintf("allocuvm out of memory\n");
 | 
			
		||||
        deallocuvm(pgdir, addr, sz);
 | 
			
		||||
        return 0;
 | 
			
		||||
      }
 | 
			
		||||
      memset(mem, 0, PGSIZE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue