Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ovs-thread: Do not always end quiescent state in ovs_thread_create().
A new thread must be started in a non quiescent state. There is a call to ovsrcu_quiesce_end() in ovsthread_wrapper(), to enforce this. ovs_thread_create(), instead, is executed in the parent thread. It must call ovsrcu_quiesce_end() on its first invocation, to put the main thread in a non quiescent state. On every other invocation, it doesn't make sense to alter the calling thread state, so this commits wraps the call to ovsrcu_quiesce_end() in an ovsthread_once construct. This fixes a bug in ovs-rcu where the first call in the process to ovsrcu_quiesce_start() will not be honored, because the calling thread will need to create the 'urcu' thread (and creating a thread will wrongly end its quiescent state). ovsrcu_quiesce_start() ovs_rcu_quiesced() if (ovsthread_once_start(&once)) { ovs_thread_create("urcu") /*This will end the quiescent state*/ } This bug affects in particular ovs-vswitchd with DPDK. In the DPDK case the first threads created are "vhost_thread" and "dpdk_watchdog". If dpdk_watchdog is the first to call ovsrcu_quiesce_start() (via xsleep()), the call is not honored and the RCU grace period lasts at least for DPDK_PORT_WATCHDOG_INTERVAL (5s on current master). If vhost_thread, on the other hand, is the first to call ovsrcu_quiesce_start(), the call is not honored and the RCU grace period lasts undefinitely, because no more calls to ovsrcu_quiesce_start() are issued from vhost_thread. For some reason (it's a race condition after all), on current master, dpdk_watchdog will always be the first to call ovsrcu_quiesce_start(), but with the upcoming DPDK database configuration changes, sometimes vhost_thread will issue the first call to ovsrcu_quiesce_start(). Sample ovs-vswitchd.log: 2016-03-23T22:34:28.532Z|00004|ovs_rcu(urcu3)|WARN|blocked 8000 ms waiting for vhost_thread2 to quiesce 2016-03-23T22:34:30.501Z|00118|ovs_rcu|WARN|blocked 8000 ms waiting for vhost_thread2 to quiesce 2016-03-23T22:34:36.532Z|00005|ovs_rcu(urcu3)|WARN|blocked 16000 ms waiting for vhost_thread2 to quiesce 2016-03-23T22:34:38.501Z|00119|ovs_rcu|WARN|blocked 16000 ms waiting for vhost_thread2 to quiesce The commit also adds a test for the ovs-rcu module to make sure that: * A new thread is started in a non quiescent state. * The first call to ovsrcu_quiesce_start() is honored. * When a process becomes multithreaded the main thread is put in an active state Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com> Acked-by: Ben Pfaff <blp@ovn.org>
- Loading branch information