rcu: Do not let RCU callbacks block on RCU
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Jun 2018 16:11:12 +0000 (12:11 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Jun 2018 16:11:12 +0000 (12:11 -0400)
commit567d6f11934b0105bc3348825a8cf2fa50cb957d
treebbdb3717c907d60501069447f62801561aa6bb87
parent5f178b4f958ccf448761c40c58fba10e3e8e7ddf
rcu: Do not let RCU callbacks block on RCU

The callbacks are run from a ktask.  If the callbacks attempt to block on
RCU with e.g. rcu_barrier() or synchronize_rcu(), we'll deadlock.  The
ktask blocks on RCU callbacks, but the ktask is the only thing that will
run the callbacks.

As far as I can tell, this is also illegal on Linux.  For instance, this
will throw a bunch of errors at runtime on Linux:

static void __cb(struct rcu_head *h)
{
    printk(KERN_INFO "about to sync\n");
    // works only if we comment this out, dies otherwise
    synchronize_rcu();
}

static void foo(void)
{
    struct rcu_head head[1];

    init_rcu_head_on_stack(head);
    call_rcu(head, __cb);
    rcu_barrier();
    destroy_rcu_head_on_stack(head);
}

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/kthread.h
kern/src/rcu.c