Don't chan_release() from an RCU callback

RCU callbacks are not allowed to block.  chan_release(), which is triggered
by decreffing a chan, can be triggered from an RCU callback.

Here's an example of a callchain that would have panicked:

 #01 [<0xffffffffc200b7c2>] in sem_down  (block here)
 #02 [<0xffffffffc200c221>] in cv_wait
 #03 [<0xffffffffc204ee05>] in rendez_sleep (this actually panics now)
 #04 [<0xffffffffc2039fa4>] in __qbread
 #05 [<0xffffffffc207c014>] in doread
 #06 [<0xffffffffc207c901>] in mntrpcread
 #07 [<0xffffffffc207d1a5>] in mountio
 #08 [<0xffffffffc207d3b5>] in mountrpc
 #09 [<0xffffffffc207dbfd>] in mntclunk
 #10 [<0xffffffffc2031448>] in chan_release
 #11 [<0xffffffffc2030bcb>] in kref_put
 #12 [<0xffffffffc2078be0>] in gtfs_tf_free
 #13 [<0xffffffffc2042125>] in __tf_free
 #14 [<0xffffffffc204f7e2>] in rcu_mgmt_ktask
 #15 [<0xffffffffc200acc0>] in __ktask_wrapper
 #16 [<0xffffffffc205981f>] in process_routine_kmsg
 #17 [<0xffffffffc20534a8>] in __smp_idle

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/src/ns/chan.c b/kern/src/ns/chan.c
index 9e42ff9..b7d6a1d 100644
--- a/kern/src/ns/chan.c
+++ b/kern/src/ns/chan.c
@@ -158,6 +158,13 @@
 {
 	struct chan *c = container_of(kref, struct chan, ref);
 	ERRSTACK(1);
+
+	/* We can be called from RCU callbacks, but close methods can block.  In
+	 * those cases, we need to defer our work to a kernel message. */
+	if (in_rcu_cb_ctx(this_pcpui_ptr())) {
+		run_as_rkm(chan_release, kref);
+		return;
+	}
 	/* this style discards the error from close().  picture it as
 	 * if (waserror()) { } else { close(); } chanfree_no_matter_what();  */
 	if (!waserror()) {