From 8af1edae0e220d79aada134845d869d1792c77f6 Mon Sep 17 00:00:00 2001 From: Geoffrey Challen Date: Thu, 9 Feb 2017 09:49:03 -0500 Subject: [PATCH] Hang detection additions. --- kern/include/cpu.h | 5 +++ kern/include/hangman.h | 84 +++++++++++++++++++++++++++++++++++++++++ kern/include/lib.h | 2 +- kern/include/mainbus.h | 3 ++ kern/include/spinlock.h | 7 ++++ kern/include/synch.h | 1 + kern/include/thread.h | 1 + kern/include/version.h | 2 +- 8 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 kern/include/hangman.h diff --git a/kern/include/cpu.h b/kern/include/cpu.h index cd386ec..687df77 100644 --- a/kern/include/cpu.h +++ b/kern/include/cpu.h @@ -87,6 +87,11 @@ struct cpu { struct tlbshootdown c_shootdown[TLBSHOOTDOWN_MAX]; unsigned c_numshootdown; struct spinlock c_ipi_lock; + + /* + * Accessed by other cpus. Protected inside hangman.c. + */ + HANGMAN_ACTOR(c_hangman); }; /* diff --git a/kern/include/hangman.h b/kern/include/hangman.h new file mode 100644 index 0000000..91f3de2 --- /dev/null +++ b/kern/include/hangman.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HANGMAN_H +#define HANGMAN_H + +/* + * Simple deadlock detector. Enable with "options hangman" in the + * kernel config. + */ + +#include "opt-hangman.h" + +#if OPT_HANGMAN + +struct hangman_actor { + const char *a_name; + const struct hangman_lockable *a_waiting; +}; + +struct hangman_lockable { + const char *l_name; + const struct hangman_actor *l_holding; +}; + +void hangman_wait(struct hangman_actor *a, struct hangman_lockable *l); +void hangman_acquire(struct hangman_actor *a, struct hangman_lockable *l); +void hangman_release(struct hangman_actor *a, struct hangman_lockable *l); + +#define HANGMAN_ACTOR(sym) struct hangman_actor sym +#define HANGMAN_LOCKABLE(sym) struct hangman_lockable sym + +#define HANGMAN_ACTORINIT(a, n) ((a)->a_name = (n), (a)->a_waiting = NULL) +#define HANGMAN_LOCKABLEINIT(l, n) ((l)->l_name = (n), (l)->l_holding = NULL) + +#define HANGMAN_LOCKABLE_INITIALIZER { "spinlock", NULL } + +#define HANGMAN_WAIT(a, l) hangman_wait(a, l) +#define HANGMAN_ACQUIRE(a, l) hangman_acquire(a, l) +#define HANGMAN_RELEASE(a, l) hangman_release(a, l) + +#else + +#define HANGMAN_ACTOR(sym) +#define HANGMAN_LOCKABLE(sym) + +#define HANGMAN_ACTORINIT(a, name) +#define HANGMAN_LOCKABLEINIT(a, name) + +#define HANGMAN_LOCKABLE_INITIALIZER + +#define HANGMAN_WAIT(a, l) +#define HANGMAN_ACQUIRE(a, l) +#define HANGMAN_RELEASE(a, l) + +#endif + +#endif /* HANGMAN_H */ diff --git a/kern/include/lib.h b/kern/include/lib.h index 7478ce6..66e5da3 100644 --- a/kern/include/lib.h +++ b/kern/include/lib.h @@ -192,7 +192,7 @@ void kprintf_bootstrap(void); */ #define DIVROUNDUP(a,b) (((a)+(b)-1)/(b)) -#define ROUNDUP(a,b) (DIVROUNDUP(a,b)*b) +#define ROUNDUP(a,b) (DIVROUNDUP(a,b)*(b)) #endif /* _LIB_H_ */ diff --git a/kern/include/mainbus.h b/kern/include/mainbus.h index 3ebbdea..4d7fff0 100644 --- a/kern/include/mainbus.h +++ b/kern/include/mainbus.h @@ -55,6 +55,9 @@ size_t mainbus_ramsize(void); /* Switch on an inter-processor interrupt. (Low-level.) */ void mainbus_send_ipi(struct cpu *target); +/* Request breaking into the debugger, where available. */ +void mainbus_debugger(void); + /* * The various ways to shut down the system. (These are very low-level * and should generally not be called directly - md_poweroff, for diff --git a/kern/include/spinlock.h b/kern/include/spinlock.h index d3b0ca0..e28ec90 100644 --- a/kern/include/spinlock.h +++ b/kern/include/spinlock.h @@ -36,6 +36,7 @@ */ #include +#include /* Inlining support - for making sure an out-of-line copy gets built */ #ifndef SPINLOCK_INLINE @@ -57,12 +58,18 @@ struct spinlock { volatile spinlock_data_t splk_lock; /* Memory word where we spin. */ struct cpu *splk_holder; /* CPU holding this lock. */ + HANGMAN_LOCKABLE(splk_hangman); /* Deadlock detector hook. */ }; /* * Initializer for cases where a spinlock needs to be static or global. */ +#ifdef OPT_HANGMAN +#define SPINLOCK_INITIALIZER { SPINLOCK_DATA_INITIALIZER, NULL, \ + HANGMAN_LOCKABLE_INITIALIZER } +#else #define SPINLOCK_INITIALIZER { SPINLOCK_DATA_INITIALIZER, NULL } +#endif /* * Spinlock functions. diff --git a/kern/include/synch.h b/kern/include/synch.h index fee3b07..0431cd3 100644 --- a/kern/include/synch.h +++ b/kern/include/synch.h @@ -74,6 +74,7 @@ void V(struct semaphore *); */ struct lock { char *lk_name; + HANGMAN_LOCKABLE(lk_hangman); /* Deadlock detector hook. */ // add what you need here // (don't forget to mark things volatile as needed) }; diff --git a/kern/include/thread.h b/kern/include/thread.h index 48ca76d..8017994 100644 --- a/kern/include/thread.h +++ b/kern/include/thread.h @@ -83,6 +83,7 @@ struct thread { struct switchframe *t_context; /* Saved register context (on stack) */ struct cpu *t_cpu; /* CPU thread runs on */ struct proc *t_proc; /* Process thread belongs to */ + HANGMAN_ACTOR(t_hangman); /* Deadlock detector hook */ /* * Interrupt state fields. diff --git a/kern/include/version.h b/kern/include/version.h index 43f66be..4d9fa1c 100644 --- a/kern/include/version.h +++ b/kern/include/version.h @@ -34,7 +34,7 @@ * Leave this alone, so we can tell what version of the OS/161 base * code we gave you. */ -#define BASE_VERSION "2.0.2" +#define BASE_VERSION "2.0.3" /* * Change this as you see fit in the course of hacking the system.