diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2020-08-13 09:19:23 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2020-08-13 09:19:23 -0400 | 
| commit | 4c22c54480f020c36de120ce868912c022e48113 (patch) | |
| tree | 89a18124f59195101aaf6959075a21a6078495a5 | |
| parent | 70c6fe861e64195032083a9fd59a81bd113d1b0b (diff) | |
| download | xv6-labs-4c22c54480f020c36de120ce868912c022e48113.tar.gz xv6-labs-4c22c54480f020c36de120ce868912c022e48113.tar.bz2 xv6-labs-4c22c54480f020c36de120ce868912c022e48113.zip | |
try to handle a few of the possible out-of-memory errors in fork()
| -rw-r--r-- | kernel/proc.c | 23 | 
1 files changed, 18 insertions, 5 deletions
| diff --git a/kernel/proc.c b/kernel/proc.c index 1774add..2811142 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -17,6 +17,7 @@ struct spinlock pid_lock;  extern void forkret(void);  static void wakeup1(struct proc *chan); +static void freeproc(struct proc *p);  extern char trampoline[]; // trampoline.S @@ -87,7 +88,7 @@ allocpid() {  // Look in the process table for an UNUSED proc.  // If found, initialize state required to run in the kernel,  // and return with p->lock held. -// If there are no free procs, return 0. +// If there are no free procs, or a memory allocation fails, return 0.  static struct proc*  allocproc(void)  { @@ -114,6 +115,11 @@ found:    // An empty user page table.    p->pagetable = proc_pagetable(p); +  if(p->pagetable == 0){ +    freeproc(p); +    release(&p->lock); +    return 0; +  }    // Set up new context to start executing at forkret,    // which returns to user space. @@ -160,12 +166,19 @@ proc_pagetable(struct proc *p)    // at the highest user virtual address.    // only the supervisor uses it, on the way    // to/from user space, so not PTE_U. -  mappages(pagetable, TRAMPOLINE, PGSIZE, -           (uint64)trampoline, PTE_R | PTE_X); +  if(mappages(pagetable, TRAMPOLINE, PGSIZE, +              (uint64)trampoline, PTE_R | PTE_X) < 0){ +    uvmfree(pagetable, 0); +    return 0; +  }    // map the trapframe just below TRAMPOLINE, for trampoline.S. -  mappages(pagetable, TRAPFRAME, PGSIZE, -           (uint64)(p->trapframe), PTE_R | PTE_W); +  if(mappages(pagetable, TRAPFRAME, PGSIZE, +              (uint64)(p->trapframe), PTE_R | PTE_W) < 0){ +    uvmunmap(pagetable, TRAMPOLINE, 1, 0); +    uvmfree(pagetable, 0); +    return 0; +  }    return pagetable;  } | 
