From 4672f514591f0f7110103c4cd898909aef95b635 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sat, 14 Mar 2015 14:17:03 +0100 Subject: Fix region allocator (see changes in region.c!) ; debug spam control. --- src/common/libkogata/slab_alloc.c | 5 +---- src/kernel/config.h | 6 ++++++ src/kernel/core/frame.c | 1 + src/kernel/core/region.c | 14 ++++++++++++-- src/kernel/core/thread.c | 27 +++++++++++++++------------ src/kernel/user/ipc.c | 6 +++--- src/kernel/user/process.c | 3 --- src/kernel/user/vfs.c | 14 +++++++------- src/lib/libkogata/user_region.c | 14 ++++++++++++-- src/tests/ktests/run_qemu_test.sh | 2 +- src/tests/utests/run_qemu_test.sh | 2 +- 11 files changed, 59 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/common/libkogata/slab_alloc.c b/src/common/libkogata/slab_alloc.c index daa3a50..0736655 100644 --- a/src/common/libkogata/slab_alloc.c +++ b/src/common/libkogata/slab_alloc.c @@ -238,10 +238,7 @@ void slab_free(mem_allocator_t* a, void* addr) { // check the object is not already on the free list (double-free error) for (object_t *i = r->first_free_obj; i != 0; i = i->next) { - if (!((void*)i >= r->region_addr && (void*)i < r->region_addr + region_size)){ - dbg_printf("Invalid object 0x%p in cache 0x%p - %x\n", i, r->region_addr, region_size); - PANIC("Error"); - } + ASSERT((void*)i >= r->region_addr && (void*)i < r->region_addr + region_size); ASSERT(o != i); } diff --git a/src/kernel/config.h b/src/kernel/config.h index f50a4ff..4d5d01f 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -26,4 +26,10 @@ #define DBGLOG_TO_SERIAL //#define DBGLOG_TO_SCREEN +// Several message types that spam the debug console +#define SPAM_CONTEXT_SWITCH 0 // show each context switch +#define SPAM_WAIT_RESUME_ON 0 // trace wait_on and resume_on calls +#define SPAM_FS_REF 0 // show reference inc/dec on VFS items +#define SPAM_BEGIN_EXIT 1 // trace thread creation/deletion && process begin/exit + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/core/frame.c b/src/kernel/core/frame.c index 255abb6..e74f9ad 100644 --- a/src/kernel/core/frame.c +++ b/src/kernel/core/frame.c @@ -54,6 +54,7 @@ uint32_t frame_alloc(size_t n) { mutex_unlock(&frame_allocator_mutex); /*dbg_printf("AF 0x%p\n", i * 32 + j);*/ + return i * 32 + j; } } diff --git a/src/kernel/core/region.c b/src/kernel/core/region.c index 886c9fc..6a4c7b4 100644 --- a/src/kernel/core/region.c +++ b/src/kernel/core/region.c @@ -55,6 +55,9 @@ void remove_free_region(descriptor_t *d) { first_free_region_by_size = d->free.next_by_size; } else { for (descriptor_t *i = first_free_region_by_size; i != 0; i = i->free.next_by_size) { + if (i->free.first_bigger == d) { + i->free.first_bigger = d->free.next_by_size; + } if (i->free.next_by_size == d) { i->free.next_by_size = d->free.next_by_size; break; @@ -382,7 +385,9 @@ void dbg_print_region_info() { } dbg_printf("- Free kernel regions, by size:\n"); for (descriptor_t *d = first_free_region_by_size; d != 0; d = d->free.next_by_size) { - dbg_printf("| 0x%p - 0x%p\n", d->free.addr, d->free.addr + d->free.size); + dbg_printf("| 0x%p - 0x%p ", d->free.addr, d->free.addr + d->free.size); + dbg_printf("(0x%p, next in size: 0x%p)\n", d->free.size, + (d->free.first_bigger == 0 ? 0 : d->free.first_bigger->free.addr)); ASSERT(d != d->free.next_by_size); } dbg_printf("- Used kernel regions:\n"); @@ -390,7 +395,12 @@ void dbg_print_region_info() { dbg_printf("| 0x%p - 0x%p %s\n", d->used.i.addr, d->used.i.addr + d->used.i.size, d->used.i.type); ASSERT(d != d->used.next_by_addr); } - dbg_printf("\\\n"); + + int nfreerd = 0; + for (descriptor_t *i = first_unused_descriptor; i != 0; i = i->unused_descriptor.next) + nfreerd++; + + dbg_printf("\\ Free region descriptors: %d (%d)\n", nfreerd, n_unused_descriptors); mutex_unlock(&ra_mutex); } diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index c4d4f93..4a3722d 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -129,7 +129,7 @@ void run_scheduler() { } current_thread = dequeue_thread(); - if (current_thread != prev_thread) dbg_printf("[0x%p]\n", current_thread); + if (current_thread != prev_thread && SPAM_CONTEXT_SWITCH) dbg_printf("[0x%p]\n", current_thread); if (current_thread != 0) { thread_t *ptr = current_thread; @@ -149,7 +149,7 @@ void run_scheduler() { void run_thread(void (*entry)(void*), void* data) { ASSERT(current_thread->state == T_STATE_RUNNING); - dbg_printf("Begin thread 0x%p (in process %d)\n", + if (SPAM_BEGIN_EXIT) dbg_printf("Begin thread 0x%p (in process %d)\n", current_thread, (current_thread->proc ? current_thread->proc->pid : 0)); switch_pagedir(get_kernel_pagedir()); @@ -176,6 +176,7 @@ thread_t *new_thread(entry_t entry, void* data) { uint32_t f; int tries = 0; while ((f = frame_alloc(1)) == 0 && (tries++) < 3) { + dbg_printf("thread stack alloc OOM\n"); free_some_memory(); } if (f == 0) { @@ -220,7 +221,7 @@ thread_t *new_thread(entry_t entry, void* data) { void delete_thread(thread_t *t) { ASSERT(t->state == T_STATE_FINISHED); - dbg_printf("Deleting thread 0x%p\n", t); + if (SPAM_BEGIN_EXIT) dbg_printf("Deleting thread 0x%p\n", t); region_free_unmap_free(t->stack_region->addr); free(t); @@ -289,11 +290,13 @@ bool wait_on_many(void** x, size_t n) { // ---- Set ourselves as the waiting thread for all the requested objets - /*dbg_printf("Wait on many:");*/ - /*for (size_t i = 0; i < n; i++) {*/ - /*dbg_printf(" 0x%p", x[i]);*/ - /*}*/ - /*dbg_printf("\n");*/ + if (SPAM_WAIT_RESUME_ON) { + dbg_printf("Wait on many:"); + for (size_t i = 0; i < n; i++) { + dbg_printf(" 0x%p", x[i]); + } + dbg_printf("\n"); + } current_thread->waiting_on = x; current_thread->n_waiting_on = n; @@ -363,7 +366,7 @@ void exit() { // (it may switch before adding the delete_thread task), but once the task is added // no other switch may happen, therefore this thread will not get re-enqueued - dbg_printf("Thread 0x%p exiting.\n", current_thread); + if (SPAM_BEGIN_EXIT) dbg_printf("Thread 0x%p exiting.\n", current_thread); worker_push(exit_cleanup_task, current_thread); @@ -379,12 +382,12 @@ bool resume_on(void* x) { int st = enter_critical(CL_NOINT); - /*dbg_printf("Resume on 0x%p:", x);*/ + if (SPAM_WAIT_RESUME_ON) dbg_printf("Resume on 0x%p:", x); for (thread_t *t = waiters; t != 0; t = t->next_waiter) { for (int i = 0; i < t->n_waiting_on; i++) { if (t->waiting_on[i] == x) { - /*dbg_printf(" 0x%p", t);*/ + if (SPAM_WAIT_RESUME_ON) dbg_printf(" 0x%p", t); if (t->state == T_STATE_PAUSED) { t->state = T_STATE_RUNNING; @@ -397,7 +400,7 @@ bool resume_on(void* x) { } } } - /*dbg_printf("\n");*/ + if (SPAM_WAIT_RESUME_ON) dbg_printf("\n"); exit_critical(st); diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c index 2a43da1..0287793 100644 --- a/src/kernel/user/ipc.c +++ b/src/kernel/user/ipc.c @@ -85,8 +85,8 @@ fs_handle_pair_t make_channel(bool blocking) { ret.a->mode = ret.b->mode = FM_READ | FM_WRITE | (blocking ? FM_BLOCKING : 0); ret.a->lock = ret.b->lock = MUTEX_UNLOCKED; - dbg_printf("hREF1c0x%p\n", ret.a); - dbg_printf("hREF1c0x%p\n", ret.b); + if (SPAM_FS_REF) dbg_printf("hREF1c0x%p\n", ret.a); + if (SPAM_FS_REF) dbg_printf("hREF1c0x%p\n", ret.b); return ret; @@ -281,7 +281,7 @@ fs_handle_t* make_shm(size_t size) { h->lock = MUTEX_UNLOCKED; h->mode = FM_READ | FM_WRITE | FM_MMAP; - dbg_printf("hREF1s0x%p\n", h); + if (SPAM_FS_REF) dbg_printf("hREF1s0x%p\n", h); return h; diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index 320638d..d96b486 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -449,8 +449,6 @@ bool proc_add_fs(process_t *p, fs_t *fs, const char* name) { if (hashtbl_find(p->filesystems, n) != 0) goto end; add_ok = hashtbl_add(p->filesystems, n, fs); - - dbg_printf("Bind %s: 0x%p\n", name, fs); end: mutex_unlock(&p->lock); @@ -601,7 +599,6 @@ error: } bool mmap_file(process_t *proc, fs_handle_t *h, size_t offset, void* addr, size_t size, int mode) { - dbg_printf("Mmap file 0x%p\n", h); if (find_user_region(proc, addr) != 0) return false; if ((uint32_t)addr & (~PAGE_MASK)) return false; diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index db01888..fa226f8 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -50,7 +50,7 @@ fs_t *make_fs(const char* drv_name, fs_handle_t *source, const char* opts) { fs->root->parent = 0; fs->root->children = 0; - dbg_printf("sREF1m0x%p\n", fs); + if (SPAM_FS_REF) dbg_printf("sREF1m0x%p\n", fs); // Look for driver for(fs_driver_t *i = drivers; i != 0; i = i->next) { @@ -88,7 +88,7 @@ fs_t *fs_subfs(fs_t *fs, const char* root, int ok_modes) { subfs->root = new_root; - dbg_printf("sREF1s0x%p\n", fs); + if (SPAM_FS_REF) dbg_printf("sREF1s0x%p\n", fs); return subfs; } @@ -98,7 +98,7 @@ bool fs_add_source(fs_t *fs, fs_handle_t *source, const char* opts) { } void ref_fs(fs_t *fs) { - dbg_printf("sREF++0x%p(%d)\n", fs, fs->refs); + if (SPAM_FS_REF) dbg_printf("sREF++0x%p(%d)\n", fs, fs->refs); mutex_lock(&fs->lock); @@ -108,7 +108,7 @@ void ref_fs(fs_t *fs) { } void unref_fs(fs_t *fs) { - dbg_printf("sREF--0x%p(%d)\n", fs, fs->refs); + if (SPAM_FS_REF) dbg_printf("sREF--0x%p(%d)\n", fs, fs->refs); mutex_lock(&fs->lock); @@ -456,7 +456,7 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) { h->node = n; h->mode = mode; - dbg_printf("hREF1o0x%p\n", h); + if (SPAM_FS_REF) dbg_printf("hREF1o0x%p\n", h); // our reference to node n is transferred to the file handle mutex_unlock(&n->lock); @@ -471,7 +471,7 @@ error: } void ref_file(fs_handle_t *file) { - dbg_printf("hREF++0x%p(%d)\n", file, file->refs); + if (SPAM_FS_REF) dbg_printf("hREF++0x%p(%d)\n", file, file->refs); mutex_lock(&file->lock); @@ -481,7 +481,7 @@ void ref_file(fs_handle_t *file) { } void unref_file(fs_handle_t *file) { - dbg_printf("hREF--0x%p(%d)\n", file, file->refs); + if (SPAM_FS_REF) dbg_printf("hREF--0x%p(%d)\n", file, file->refs); mutex_lock(&file->lock); diff --git a/src/lib/libkogata/user_region.c b/src/lib/libkogata/user_region.c index 516259b..14c0898 100644 --- a/src/lib/libkogata/user_region.c +++ b/src/lib/libkogata/user_region.c @@ -56,6 +56,9 @@ static void remove_free_region(descriptor_t *d) { first_free_region_by_size = d->free.next_by_size; } else { for (descriptor_t *i = first_free_region_by_size; i != 0; i = i->free.next_by_size) { + if (i->free.first_bigger == d) { + i->free.first_bigger = d->free.next_by_size; + } if (i->free.next_by_size == d) { i->free.next_by_size = d->free.next_by_size; break; @@ -337,7 +340,9 @@ void dbg_print_region_info() { } dbg_printf("- Free process regions, by size:\n"); for (descriptor_t *d = first_free_region_by_size; d != 0; d = d->free.next_by_size) { - dbg_printf("| 0x%p - 0x%p\n", d->free.addr, d->free.addr + d->free.size); + dbg_printf("| 0x%p - 0x%p ", d->free.addr, d->free.addr + d->free.size); + dbg_printf("(0x%p, next in size: 0x%p)\n", d->free.size, + (d->free.first_bigger == 0 ? 0 : d->free.first_bigger->free.addr)); ASSERT(d != d->free.next_by_size); } dbg_printf("- Used process regions:\n"); @@ -345,7 +350,12 @@ void dbg_print_region_info() { dbg_printf("| 0x%p - 0x%p %s\n", d->used.i.addr, d->used.i.addr + d->used.i.size, d->used.i.type); ASSERT(d != d->used.next_by_addr); } - dbg_printf("\\\n"); + + int nfreerd = 0; + for (descriptor_t *i = first_unused_descriptor; i != 0; i = i->unused_descriptor.next) + nfreerd++; + + dbg_printf("\\ Free region descriptors: %d (%d)\n", nfreerd, n_unused_descriptors); mutex_unlock(&ra_mutex); } diff --git a/src/tests/ktests/run_qemu_test.sh b/src/tests/ktests/run_qemu_test.sh index 3f5c934..0e7b83e 100755 --- a/src/tests/ktests/run_qemu_test.sh +++ b/src/tests/ktests/run_qemu_test.sh @@ -1,6 +1,6 @@ #!/bin/bash -(qemu-system-i386 -kernel test_kernel.bin -initrd ../../kernel/kernel.map -serial stdio -m 64 -display none & echo $! >pid) \ +(qemu-system-i386 -kernel test_kernel.bin -initrd ../../kernel/kernel.map -serial stdio -m 16 -display none & echo $! >pid) \ | tee >(grep -m 1 "TEST-" >result; kill -INT `cat pid`) \ RESULT=`cat result` diff --git a/src/tests/utests/run_qemu_test.sh b/src/tests/utests/run_qemu_test.sh index a1f804d..c168e8c 100755 --- a/src/tests/utests/run_qemu_test.sh +++ b/src/tests/utests/run_qemu_test.sh @@ -9,7 +9,7 @@ if [ "$1" = "watchdog" ]; then exit 0 fi -(qemu-system-i386 -kernel ../../../kernel/kernel.bin -append 'init=io:/mod/init.bin' -initrd 'init.bin,../../../kernel/kernel.map' -serial stdio -m 64 -display none & echo $! >pid & +(qemu-system-i386 -kernel ../../../kernel/kernel.bin -append 'init=io:/mod/init.bin' -initrd 'init.bin,../../../kernel/kernel.map' -serial stdio -m 16 -display none & echo $! >pid & $0 watchdog) \ | tee >(grep -m 1 "TEST-" >result; kill -INT `cat pid`; kill -TERM `cat pid2`) \ -- cgit v1.2.3