Message ID | 55B1D380.7020300@cn.fujitsu.com |
---|---|
State | New |
Headers | show |
On 24/07/2015 07:56, Wen Congyang wrote: > @@ -115,9 +116,12 @@ static void wait_for_readers(void) > } > > /* Wait for one thread to report a quiescent state and > - * try again. > + * try again. Release rcu_gp_lock, so rcu_(un)register_thread() > + * doesn't wait too much time. > */ > + qemu_mutex_unlock(&rcu_gp_lock); > qemu_event_wait(&rcu_gp_event); > + qemu_mutex_lock(&rcu_gp_lock); > } > So in this case rcu_unregister_thread could actually remove the node from synchronize_rcu's qsreaders, not just from registry. That's a bit tricky, but it should work. Please add a comment, however. Also, please rename "rcu_gp_lock" as well to rcu_registry_lock. We'll get the patches in QEMU 2.5. Paolo
On 07/24/2015 02:22 PM, Paolo Bonzini wrote: > > > On 24/07/2015 07:56, Wen Congyang wrote: >> @@ -115,9 +116,12 @@ static void wait_for_readers(void) >> } >> >> /* Wait for one thread to report a quiescent state and >> - * try again. >> + * try again. Release rcu_gp_lock, so rcu_(un)register_thread() >> + * doesn't wait too much time. >> */ >> + qemu_mutex_unlock(&rcu_gp_lock); >> qemu_event_wait(&rcu_gp_event); >> + qemu_mutex_lock(&rcu_gp_lock); >> } >> > > So in this case rcu_unregister_thread could actually remove the node > from synchronize_rcu's qsreaders, not just from registry. That's a bit > tricky, but it should work. Please add a comment, however. > > Also, please rename "rcu_gp_lock" as well to rcu_registry_lock. We'll > get the patches in QEMU 2.5. OK, I will do it. Thanks Wen Congyang > > Paolo > . >
diff --git a/util/rcu.c b/util/rcu.c index 7270151..ccf8cfa 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -48,6 +48,7 @@ unsigned long rcu_gp_ctr = RCU_GP_LOCKED; QemuEvent rcu_gp_event; static QemuMutex rcu_gp_lock; +static QemuMutex rcu_sync_lock; /* * Check whether a quiescent state was crossed between the beginning of @@ -115,9 +116,12 @@ static void wait_for_readers(void) } /* Wait for one thread to report a quiescent state and - * try again. + * try again. Release rcu_gp_lock, so rcu_(un)register_thread() + * doesn't wait too much time. */ + qemu_mutex_unlock(&rcu_gp_lock); qemu_event_wait(&rcu_gp_event); + qemu_mutex_lock(&rcu_gp_lock); } /* put back the reader list in the registry */ @@ -126,6 +130,7 @@ static void wait_for_readers(void) void synchronize_rcu(void) { + qemu_mutex_lock(&rcu_sync_lock); qemu_mutex_lock(&rcu_gp_lock); if (!QLIST_EMPTY(®istry)) { @@ -150,6 +155,7 @@ void synchronize_rcu(void) } qemu_mutex_unlock(&rcu_gp_lock); + qemu_mutex_unlock(&rcu_sync_lock); } @@ -288,6 +294,7 @@ static void rcu_init_complete(void) QemuThread thread; qemu_mutex_init(&rcu_gp_lock); + qemu_mutex_init(&rcu_sync_lock); qemu_event_init(&rcu_gp_event, true); qemu_event_init(&rcu_call_ready_event, false); @@ -304,12 +311,14 @@ static void rcu_init_complete(void) #ifdef CONFIG_POSIX static void rcu_init_lock(void) { + qemu_mutex_lock(&rcu_sync_lock); qemu_mutex_lock(&rcu_gp_lock); } static void rcu_init_unlock(void) { qemu_mutex_unlock(&rcu_gp_lock); + qemu_mutex_unlock(&rcu_sync_lock); } #endif