summaryrefslogtreecommitdiff
path: root/kernel/proc.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2020-08-13 09:19:23 -0400
committerFrans Kaashoek <[email protected]>2020-08-17 08:18:23 -0400
commitbc51626aab45f420652f20948a1ffa5398ad9446 (patch)
tree89a18124f59195101aaf6959075a21a6078495a5 /kernel/proc.c
parenta8dd44cf595bb691ec21a16e01eaaf9b527a05ca (diff)
downloadxv6-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.c23
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;
}