Add a monitor debug function for rendez waiters

When debugging, it's helpful to be able to tell what is waiting on a
particular rendez.  "db rv 0xWAITER" will do the trick.

Like many monitor commands, this is dangerous.  Not only will it cast
whatever you pass it to an alarm_waiter, but even if you don't mess up,
there's no telling that the alarm isn't currently firing and unwinding
the stack.  That being said, it's been useful for me.

Usage:

(akaros) / $ m alarm pcpu
PCPU Chains:  It is now [    189.392342216]
Chain 0xffffffffcc683c48:  earliest: [    189.399452912] latest: [    482.049028825]
	Waiter 0xffffffffcc683ac0, time [    189.399452912] (0x0000008cc62c95fa), func 0xffffffffc205a740 (__ksched_tick)
	Waiter 0xfffffff000097dd8, time [    189.416393761] (0x0000008cc965c92b), func 0xffffffffc20586e0 (rendez_alarm_handler)
	Waiter 0xfffffff0000a9c98, time [    482.049028825] (0x000001664a5eef19), func 0xffffffffc20586e0 (rendez_alarm_handler)
Chain 0xffffffffcc683f08:  earliest: [    189.477399144] latest: [    189.477399144]
	Waiter 0xfffffff0000a6cb8, time [    189.477399144] (0x0000008cd50165fa), func 0xffffffffc20586e0 (rendez_alarm_handler)

(akaros) / $ m db rv 0xfffffff0000a6cb8
-------- kth #I0tcpack ----------

Backtrace of kernel context on Core 0:
 #01 [<0xffffffffc20145ab>] in cv_wait_and_unlock
 #02 [<0xffffffffc2014651>] in cv_wait
 #03 [<0xffffffffc20585cd>] in rendez_sleep_timeout
 #04 [<0xffffffffc2013d72>] in kthread_usleep
 #05 [<0xffffffffc20327a4>] in tcpackproc
 #06 [<0xffffffffc2013274>] in __ktask_wrapper
 #07 [<0xffffffffc2063bad>] in process_routine_kmsg
 #08 [<0xffffffffc205d59e>] in __smp_idle
-----------------

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/include/rendez.h b/kern/include/rendez.h
index f607105..06f257a 100644
--- a/kern/include/rendez.h
+++ b/kern/include/rendez.h
@@ -39,6 +39,7 @@
 
 #include <ros/common.h>
 #include <kthread.h>
+#include <alarm.h>
 
 struct rendez {
 	struct cond_var				cv;
@@ -51,3 +52,4 @@
 void rendez_sleep_timeout(struct rendez *rv, int (*cond)(void*), void *arg,
                           uint64_t usec);
 bool rendez_wakeup(struct rendez *rv);
+void rendez_debug_waiter(struct alarm_waiter *awaiter);
diff --git a/kern/src/monitor.c b/kern/src/monitor.c
index 3f26125..8c137fd 100644
--- a/kern/src/monitor.c
+++ b/kern/src/monitor.c
@@ -1007,6 +1007,7 @@
 		printk("Usage: db OPTION\n");
 		printk("\tblk [PID]: print all blocked kthreads\n");
 		printk("\taddr PID 0xADDR: for PID lookup ADDR's file/vmr info\n");
+		printk("\trv WAITER: backtrace rendez alarm waiter\n");
 		return 1;
 	}
 	if (!strcmp(argv[1], "blk") || !strcmp(argv[1], "sem")) {
@@ -1019,6 +1020,12 @@
 			return 1;
 		}
 		debug_addr_pid(strtol(argv[2], 0, 10), strtol(argv[3], 0, 16));
+	} else if (!strcmp(argv[1], "rv")) {
+		if (argc < 3) {
+			printk("Usage: db rv 0xWAITER\n");
+			return 1;
+		}
+		rendez_debug_waiter((struct alarm_waiter*)strtoul(argv[2], 0, 16));
 	} else {
 		printk("Bad option\n");
 		return 1;
diff --git a/kern/src/rendez.c b/kern/src/rendez.c
index 215e85f..6d5de7c 100644
--- a/kern/src/rendez.c
+++ b/kern/src/rendez.c
@@ -61,6 +61,24 @@
 	rendez_wakeup(rv);
 }
 
+void rendez_debug_waiter(struct alarm_waiter *awaiter)
+{
+	struct rendez *rv = (struct rendez*)awaiter->data;
+	struct cond_var *cv = &rv->cv;
+	struct kthread *kth;
+	int8_t irq_state = 0;
+
+	cv_lock_irqsave(cv, &irq_state);
+	TAILQ_FOREACH(kth, &cv->waiters, link) {
+		print_lock();
+		printk("-------- kth %s ----------\n", kth->name);
+		backtrace_kthread(kth);
+		printk("-----------------\n");
+		print_unlock();
+	}
+	cv_unlock_irqsave(cv, &irq_state);
+}
+
 /* Like sleep, but it will timeout in 'usec' microseconds. */
 void rendez_sleep_timeout(struct rendez *rv, int (*cond)(void*), void *arg,
                           uint64_t usec)