Fixes nasty kthread bug
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 6 May 2011 01:43:41 +0000 (18:43 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:02 +0000 (17:36 -0700)
We were freeing the stack we were about to use, which is a bad idea.
Bug showed up as TAILQ corruption (often PFs) in alarm code, and once a
non-empty semaphore in a waiter in sys_block().  The "freed" stack was
being reused for the exact same code path (another sys_block), and
occasionally for other syscalls with a deeper stack (clobbering the LL
item).

kern/src/kthread.c

index dc33820..8d360fa 100644 (file)
@@ -134,11 +134,13 @@ void restart_kthread(struct kthread *kthread)
         * free our current kthread *before* popping it, nor can we free the current
         * stack until we pop to the kthread's stack). */
        if (pcpui->spare) {
-               /* TODO: we shouldn't free a page holding current_tf */
+               /* this should never happen now.  it probably only was a concern because
+                * i accidentally free kthread's stacktop (the one i was jumping too) */
                assert(ROUNDDOWN((uintptr_t)current_tf, PGSIZE) !=
-                      kthread->stacktop - PGSIZE);
-               /* this should probably have a rounddown, since it's not always the top */
-               page_decref(kva2page((void*)kthread->stacktop - PGSIZE));
+                      pcpui->spare->stacktop - PGSIZE);
+               /* this should probably have a rounddown, since it's not always the top,
+                * or even always PGSIZE... */
+               page_decref(kva2page((void*)pcpui->spare->stacktop - PGSIZE));
                kmem_cache_free(kthread_kcache, pcpui->spare);
        }
        current_stacktop = get_stack_top();