Skip to content

Commit

Permalink
ovs-rcu: Make ovsrcu_quiesce() flush the callback event set.
Browse files Browse the repository at this point in the history
On current master, the per-thread callback event set is flushed
when ovsrcu_quiesce_start() is called or when the callback
event set is full.  For threads that only call 'ovsrcu_quiesce()'
to indicate quiescient state, their callback event set will not
be flushed for execution until the set is full.  And this could
take a very long time.

Theoretically, this should not be an issue, since rcu postponed
callback events should only free the old version of objects.
However, current ovs does not follow this rule, and some callback
events include other activities like unregistering the netdev
from global name-netdev map.  The delay of unregistering the netdev
(by threads that only calls ovsrcu_quiesce()) will prevent the
recreate of same netdev indefinitely.

As a short-term workaround, this commit makes every call to
ovsrcu_quiesce() flush the callback event set.  In the long run,
there will be a refactor of the use of ovs-rcu module, in which all
callback events only free the old version of objects.

Signed-off-by: Alex Wang <alexw@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
  • Loading branch information
yew011 committed Sep 12, 2014
1 parent b8f958e commit 9c7e020
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions lib/ovs-rcu.c
Expand Up @@ -138,8 +138,13 @@ ovsrcu_quiesce_start(void)
void
ovsrcu_quiesce(void)
{
ovsrcu_init_module();
ovsrcu_perthread_get()->seqno = seq_read(global_seqno);
struct ovsrcu_perthread *perthread;

perthread = ovsrcu_perthread_get();
perthread->seqno = seq_read(global_seqno);
if (perthread->cbset) {
ovsrcu_flush_cbset(perthread);
}
seq_change(global_seqno);

ovsrcu_quiesced();
Expand Down

0 comments on commit 9c7e020

Please sign in to comment.