diff options
author | Richard Braun <rbraun@sceen.net> | 2016-02-02 23:17:20 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2016-02-02 23:20:32 +0100 |
commit | 44d78061e90e777b51cae8e01eda5c0d3ce63103 (patch) | |
tree | 64af20619a7292834c9d66e8157e0301a8d62f0d /kern/thread.c | |
parent | 909167b9d05cf896f1e54122183ef8ee9ee70677 (diff) | |
download | gnumach-44d78061e90e777b51cae8e01eda5c0d3ce63103.tar.gz gnumach-44d78061e90e777b51cae8e01eda5c0d3ce63103.tar.bz2 gnumach-44d78061e90e777b51cae8e01eda5c0d3ce63103.zip |
Fix various memory managment errors
A few errors were introduced in the latest changes.
o Add VM_PAGE_WAIT calls around physical allocation attempts in case of
memory exhaustion.
o Fix stack release.
o Fix memory exhaustion report.
o Fix free page accounting.
* kern/slab.c (kmem_pagealloc, kmem_pagefree): New functions
(kmem_slab_create, kmem_slab_destroy, kalloc, kfree): Use kmem_pagealloc
and kmem_pagefree instead of the raw page allocation functions.
(kmem_cache_compute_sizes): Don't store slab order.
* kern/slab.h (struct kmem_cache): Remove `slab_order' member.
* kern/thread.c (stack_alloc): Call VM_PAGE_WAIT in case of memory
exhaustion.
(stack_collect): Call vm_page_free_contig instead of kmem_free to
release pages.
* vm/vm_page.c (vm_page_seg_alloc): Fix memory exhaustion report.
(vm_page_setup): Don't update vm_page_free_count.
(vm_page_free_pa): Check page parameter.
(vm_page_mem_free): New function.
* vm/vm_page.h (vm_page_free_count): Remove extern declaration.
(vm_page_mem_free): New prototype.
* vm/vm_pageout.c: Update comments not to refer to vm_page_free_count.
(vm_pageout_scan, vm_pageout_continue, vm_pageout): Use vm_page_mem_free
instead of vm_page_free_count, update types accordingly.
* vm/vm_resident.c (vm_page_free_count, vm_page_free_count_minimum):
Remove variables.
(vm_page_free_avail): New variable.
(vm_page_bootstrap, vm_page_grab, vm_page_release, vm_page_grab_contig,
vm_page_free_contig, vm_page_wait): Use vm_page_mem_free instead of vm_page_free_count,
update types accordingly, don't set vm_page_free_count_minimum.
* vm/vm_user.c (vm_statistics): Likewise.
Diffstat (limited to 'kern/thread.c')
-rw-r--r-- | kern/thread.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/kern/thread.c b/kern/thread.c index 91e08697..d8d6af57 100644 --- a/kern/thread.c +++ b/kern/thread.c @@ -197,16 +197,19 @@ kern_return_t stack_alloc( if (stack == 0) { struct vm_page *page; - /* - * 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. - */ - page = vm_page_alloc_pa(vm_page_order(KERNEL_STACK_SIZE), - VM_PAGE_SEL_DIRECTMAP, - VM_PT_STACK); - if (page == NULL) - return KERN_RESOURCE_SHORTAGE; + for (;;) { + /* + * 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. + */ + page = vm_page_grab_contig(KERNEL_STACK_SIZE, + VM_PAGE_SEL_DIRECTMAP); + if (page != NULL) + break; + + VM_PAGE_WAIT(NULL); + } stack = phystokv(vm_page_to_pa(page)); #if MACH_DEBUG @@ -254,6 +257,7 @@ void stack_free( void stack_collect(void) { + struct vm_page *page; vm_offset_t stack; spl_t s; @@ -269,7 +273,9 @@ void stack_collect(void) #if MACH_DEBUG stack_finalize(stack); #endif /* MACH_DEBUG */ - kmem_free(kmem_map, stack, KERNEL_STACK_SIZE); + page = vm_page_lookup_pa(kvtophys(stack)); + assert(page != NULL); + vm_page_free_contig(page, KERNEL_STACK_SIZE); s = splsched(); stack_lock(); |