Commit d62cb4f2 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

rcu: allow nesting of rcu_read_lock/rcu_read_unlock

parent 8fda74a5
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ struct rcu_reader_data {
    unsigned long ctr;
    bool waiting;

    /* Data used by reader only */
    unsigned depth;

    /* Data used for registry, protected by rcu_gp_lock */
    QLIST_ENTRY(rcu_reader_data) node;
};
@@ -77,8 +80,13 @@ extern __thread struct rcu_reader_data rcu_reader;
static inline void rcu_read_lock(void)
{
    struct rcu_reader_data *p_rcu_reader = &rcu_reader;
    unsigned ctr;

    if (p_rcu_reader->depth++ > 0) {
        return;
    }

    unsigned ctr = atomic_read(&rcu_gp_ctr);
    ctr = atomic_read(&rcu_gp_ctr);
    atomic_xchg(&p_rcu_reader->ctr, ctr);
    if (atomic_read(&p_rcu_reader->waiting)) {
        atomic_set(&p_rcu_reader->waiting, false);
@@ -90,6 +98,11 @@ static inline void rcu_read_unlock(void)
{
    struct rcu_reader_data *p_rcu_reader = &rcu_reader;

    assert(p_rcu_reader->depth != 0);
    if (--p_rcu_reader->depth > 0) {
        return;
    }

    atomic_xchg(&p_rcu_reader->ctr, 0);
    if (atomic_read(&p_rcu_reader->waiting)) {
        atomic_set(&p_rcu_reader->waiting, false);
+2 −0
Original line number Diff line number Diff line
@@ -255,9 +255,11 @@ static void *rcu_read_stress_test(void *arg)
        if (p->mbtest == 0) {
            n_mberror++;
        }
        rcu_read_lock();
        for (i = 0; i < 100; i++) {
            garbage++;
        }
        rcu_read_unlock();
        pc = p->pipe_count;
        rcu_read_unlock();
        if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {