diff options
author | Robert Morris <[email protected]> | 2020-08-13 09:19:23 -0400 |
---|---|---|
committer | Frans Kaashoek <[email protected]> | 2020-08-17 08:18:23 -0400 |
commit | bc51626aab45f420652f20948a1ffa5398ad9446 (patch) | |
tree | 89a18124f59195101aaf6959075a21a6078495a5 /kernel/proc.c | |
parent | a8dd44cf595bb691ec21a16e01eaaf9b527a05ca (diff) | |
download | xv6-labs-bc51626aab45f420652f20948a1ffa5398ad9446.tar.gz xv6-labs-bc51626aab45f420652f20948a1ffa5398ad9446.tar.bz2 xv6-labs-bc51626aab45f420652f20948a1ffa5398ad9446.zip |
try to handle a few of the possible out-of-memory errors in fork()
Diffstat (limited to 'kernel/proc.c')
-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; } |