[libvirt] [PATCH v2 4/4] Push nwfilter update locking up to top level
Stefan Berger
stefanb at linux.vnet.ibm.com
Mon Jan 27 21:53:53 UTC 2014
On 01/27/2014 12:18 PM, Daniel P. Berrange wrote:
> The NWFilter code has as a deadlock race condition between
> the virNWFilter{Define,Undefine} APIs and starting of guest
> VMs due to mis-matched lock ordering.
>
> In the virNWFilter{Define,Undefine} codepaths the lock ordering
> is
>
> 1. nwfilter driver lock
> 2. virt driver lock
> 3. nwfilter update lock
> 4. domain object lock
>
> In the VM guest startup paths the lock ordering is
>
> 1. virt driver lock
> 2. domain object lock
> 3. nwfilter update lock
>
> As can be seen the domain object and nwfilter update locks are
> not acquired in a consistent order.
>
> The fix used is to push the nwfilter update lock upto the top
> level resulting in a lock ordering for virNWFilter{Define,Undefine}
> of
>
> 1. nwfilter driver lock
> 2. nwfilter update lock
Insert: 3. nwfilter callback drivers lock
This is then used in this order also by nwfilterStateReload
> 3. virt driver lock
> 4. domain object lock
>
> and VM start using
>
> 1. nwfilter update lock
> 2. virt driver lock
> 3. domain object lock
>
> This has the effect of serializing VM startup once again, even if
> no nwfilters are applied to the guest. There is also the possibility
> of deadlock due to a call graph loop via virNWFilterInstantiate
> and virNWFilterInstantiateFilterLate.
>
> These two problems mean the lock must be turned into a read/write
> lock instead of a plain mutex at the same time. The lock is used to
> serialize changes to the "driver->nwfilters" hash, so the write lock
> only needs to be held by the define/undefine methods. All other
> methods can rely on a read lock which allows good concurrency.
>
> Signed-off-by: Daniel P. Berrange<berrange at redhat.com>
> ---
> src/conf/nwfilter_conf.c | 23 +++++++++++------------
> src/conf/nwfilter_conf.h | 3 ++-
> src/libvirt_private.syms | 3 ++-
> src/lxc/lxc_driver.c | 6 ++++++
> src/nwfilter/nwfilter_driver.c | 11 +++++++----
> src/nwfilter/nwfilter_gentech_driver.c | 4 +---
> src/qemu/qemu_driver.c | 6 ++++++
> src/uml/uml_driver.c | 4 ++++
> 8 files changed, 39 insertions(+), 21 deletions(-)
>
> diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
> index 112e8cb..80030c8 100644
> --- a/src/nwfilter/nwfilter_driver.c
> +++ b/src/nwfilter/nwfilter_driver.c
> @@ -285,12 +285,15 @@ nwfilterStateReload(void)
> virNWFilterLearnThreadsTerminate(true);
>
> nwfilterDriverLock(driverState);
> + virNWFilterWriteLockFilterUpdates();
> virNWFilterCallbackDriversLock();
>
> +
stray newline here
> virNWFilterLoadAllConfigs(&driverState->nwfilters,
> driverState->configDir);
>
> virNWFilterCallbackDriversUnlock();
> + virNWFilterUnlockFilterUpdates();
> nwfilterDriverUnlock(driverState);
>
> virNWFilterInstFiltersOnAllVMs();
Modulo the above stray line and then comment in the introductory text, I
think this patch is good. I am just a bit concerned about 3/4.
Stefan
More information about the libvir-list
mailing list