From 6eb79f812ee43a4e9142de61a5821e0cc8c52bb1 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 26 Apr 2015 15:47:47 +0200 Subject: kern: gracefully handle resource shortage * kern/thread.c (stack_alloc): Report resource shortage. * kern/sched_prim.h (stack_alloc): Adjust declaration accordingly. * kern/thread_swap.c (thread_doswapin): Report resource shortage. (swapin_thread_continue): If the swap-in fails, put the thread back on the queue and go back to sleep. * kern/thread_swap.h (thread_doswapin): Adjust declaration accordingly. --- kern/sched_prim.h | 2 +- kern/thread.c | 11 ++++++----- kern/thread_swap.c | 17 ++++++++++++++--- kern/thread_swap.h | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/kern/sched_prim.h b/kern/sched_prim.h index fd989b6c..62698dc2 100644 --- a/kern/sched_prim.h +++ b/kern/sched_prim.h @@ -150,7 +150,7 @@ extern void stack_handoff( * or are defined directly by machine-dependent code. */ -extern void stack_alloc( +extern kern_return_t stack_alloc( thread_t thread, void (*resume)(thread_t)); extern boolean_t stack_alloc_try( diff --git a/kern/thread.c b/kern/thread.c index 009884ce..f52c95b8 100644 --- a/kern/thread.c +++ b/kern/thread.c @@ -171,7 +171,7 @@ boolean_t stack_alloc_try( * May block. */ -void stack_alloc( +kern_return_t stack_alloc( thread_t thread, void (*resume)(thread_t)) { @@ -195,15 +195,15 @@ void stack_alloc( (void) splx(s); if (stack == 0) { + kern_return_t kr; /* * Kernel stacks should be naturally aligned, * so that it is easy to find the starting/ending * addresses of a stack given an address in the middle. */ - - if (kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE) - != KERN_SUCCESS) - panic("stack_alloc"); + kr = kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE); + if (kr != KERN_SUCCESS) + return kr; #if MACH_DEBUG stack_init(stack); @@ -211,6 +211,7 @@ void stack_alloc( } stack_attach(thread, stack, resume); + return KERN_SUCCESS; } /* diff --git a/kern/thread_swap.c b/kern/thread_swap.c index dc2924a9..20ad0409 100644 --- a/kern/thread_swap.c +++ b/kern/thread_swap.c @@ -123,15 +123,18 @@ void thread_swapin(thread_t thread) * it on a run queue. No locks should be held on entry, as it is * likely that this routine will sleep (waiting for stack allocation). */ -void thread_doswapin(thread_t thread) +kern_return_t thread_doswapin(thread_t thread) { + kern_return_t kr; spl_t s; /* * Allocate the kernel stack. */ - stack_alloc(thread, thread_continue); + kr = stack_alloc(thread, thread_continue); + if (kr != KERN_SUCCESS) + return kr; /* * Place on run queue. @@ -144,6 +147,7 @@ void thread_doswapin(thread_t thread) thread_setrun(thread, TRUE); thread_unlock(thread); (void) splx(s); + return KERN_SUCCESS; } /* @@ -163,13 +167,20 @@ void __attribute__((noreturn)) swapin_thread_continue(void) while ((thread = (thread_t) dequeue_head(&swapin_queue)) != THREAD_NULL) { + kern_return_t kr; swapper_unlock(); (void) splx(s); - thread_doswapin(thread); /* may block */ + kr = thread_doswapin(thread); /* may block */ s = splsched(); swapper_lock(); + + if (kr != KERN_SUCCESS) { + enqueue_head(&swapin_queue, + (queue_entry_t) thread); + break; + } } assert_wait((event_t) &swapin_queue, FALSE); diff --git a/kern/thread_swap.h b/kern/thread_swap.h index 9d645373..d032accf 100644 --- a/kern/thread_swap.h +++ b/kern/thread_swap.h @@ -37,7 +37,7 @@ */ extern void swapper_init(void); extern void thread_swapin(thread_t thread); -extern void thread_doswapin(thread_t thread); +extern kern_return_t thread_doswapin(thread_t thread); extern void swapin_thread(void) __attribute__((noreturn)); #endif /* _KERN_THREAD_SWAP_H_ */ -- cgit v1.2.3