mirror of https://github.com/xemu-project/xemu.git
rcu: allow nesting of rcu_read_lock/rcu_read_unlock
Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
8fda74a52b
commit
d62cb4f2fd
|
@ -68,6 +68,9 @@ struct rcu_reader_data {
|
||||||
unsigned long ctr;
|
unsigned long ctr;
|
||||||
bool waiting;
|
bool waiting;
|
||||||
|
|
||||||
|
/* Data used by reader only */
|
||||||
|
unsigned depth;
|
||||||
|
|
||||||
/* Data used for registry, protected by rcu_gp_lock */
|
/* Data used for registry, protected by rcu_gp_lock */
|
||||||
QLIST_ENTRY(rcu_reader_data) node;
|
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)
|
static inline void rcu_read_lock(void)
|
||||||
{
|
{
|
||||||
struct rcu_reader_data *p_rcu_reader = &rcu_reader;
|
struct rcu_reader_data *p_rcu_reader = &rcu_reader;
|
||||||
|
unsigned ctr;
|
||||||
|
|
||||||
unsigned ctr = atomic_read(&rcu_gp_ctr);
|
if (p_rcu_reader->depth++ > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr = atomic_read(&rcu_gp_ctr);
|
||||||
atomic_xchg(&p_rcu_reader->ctr, ctr);
|
atomic_xchg(&p_rcu_reader->ctr, ctr);
|
||||||
if (atomic_read(&p_rcu_reader->waiting)) {
|
if (atomic_read(&p_rcu_reader->waiting)) {
|
||||||
atomic_set(&p_rcu_reader->waiting, false);
|
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;
|
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);
|
atomic_xchg(&p_rcu_reader->ctr, 0);
|
||||||
if (atomic_read(&p_rcu_reader->waiting)) {
|
if (atomic_read(&p_rcu_reader->waiting)) {
|
||||||
atomic_set(&p_rcu_reader->waiting, false);
|
atomic_set(&p_rcu_reader->waiting, false);
|
||||||
|
|
|
@ -255,9 +255,11 @@ static void *rcu_read_stress_test(void *arg)
|
||||||
if (p->mbtest == 0) {
|
if (p->mbtest == 0) {
|
||||||
n_mberror++;
|
n_mberror++;
|
||||||
}
|
}
|
||||||
|
rcu_read_lock();
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
garbage++;
|
garbage++;
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
pc = p->pipe_count;
|
pc = p->pipe_count;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {
|
if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {
|
||||||
|
|
Loading…
Reference in New Issue