[PATCH] nwfilter: reorder locks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch reorders the locks for the nwfilter updates and the access the nwfilter objects. In the case that the IP address learning thread was instantiating filters while an update happened, the previous order lead to a deadlock.

I am also adding a text file describing the locking order of the nwfilter subsystem.

Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>

---
 src/conf/nwfilter_conf.c       |    9 ++++----
src/nwfilter/locking.txt | 45 +++++++++++++++++++++++++++++++++++++++++
 src/nwfilter/nwfilter_driver.c |    4 +++
 3 files changed, 54 insertions(+), 4 deletions(-)

Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -2440,15 +2440,13 @@ virNWFilterTestUnassignDef(virConnectPtr
 {
     int rc = 0;

-    virNWFilterLockFilterUpdates();
-
     nwfilter->wantRemoved = 1;
     /* trigger the update on VMs referencing the filter */
     if (virNWFilterTriggerVMFilterRebuild(conn))
         rc = 1;

     nwfilter->wantRemoved = 0;
-    virNWFilterUnlockFilterUpdates();
+
     return rc;
 }

@@ -2480,8 +2478,9 @@ virNWFilterObjAssignDef(virConnectPtr co
         return NULL;
     }

+    virNWFilterLockFilterUpdates();
+
     if ((nwfilter = virNWFilterObjFindByName(nwfilters, def->name))) {
-        virNWFilterLockFilterUpdates();
         nwfilter->newDef = def;
         /* trigger the update on VMs referencing the filter */
         if (virNWFilterTriggerVMFilterRebuild(conn)) {
@@ -2498,6 +2497,8 @@ virNWFilterObjAssignDef(virConnectPtr co
         return nwfilter;
     }

+    virNWFilterUnlockFilterUpdates();
+
     if (VIR_ALLOC(nwfilter) < 0) {
         virReportOOMError();
         return NULL;
Index: libvirt-acl/src/nwfilter/nwfilter_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_driver.c
@@ -372,6 +372,8 @@ nwfilterUndefine(virNWFilterPtr obj) {
     nwfilterDriverLock(driver);
     virNWFilterCallbackDriversLock();

+    virNWFilterLockFilterUpdates();
+
     nwfilter = virNWFilterObjFindByUUID(&driver->nwfilters, obj->uuid);
     if (!nwfilter) {
         virNWFilterReportError(VIR_ERR_NO_NWFILTER,
@@ -399,6 +401,8 @@ cleanup:
     if (nwfilter)
         virNWFilterObjUnlock(nwfilter);

+    virNWFilterUnlockFilterUpdates();
+
     virNWFilterCallbackDriversUnlock();
     nwfilterDriverUnlock(driver);
     return ret;
Index: libvirt-acl/src/nwfilter/locking.txt
===================================================================
--- /dev/null
+++ libvirt-acl/src/nwfilter/locking.txt
@@ -0,0 +1,45 @@
+NWfilter locks:
+---------------
+
+The following NWFilter functions grab locks:
+
+- nwfilterDriverLock(driverState)
+   - protects driverState
+- virNWFilterCallbackDriversLock()
+   - lock access to callback drivers
+- virNWFilterLockFilterUpdates()
+   - prevent modification of any filter in use by any VM
+- virNWFilterObjLock()
+    called by
+      - virNWFilterObjFindByUUID(),
+      - virNWFilterObjFindByName(),
+      - virNWFilterObjAssignDef()
+    and the functions return with the lock held
+
+
+NWFilter-Lock ordering:
+-----------------------
+
+Order in which the NWFilter lock functions have to be called:
+
+1. nwFilterDriverLock
+2. virNWFilterCallbackDriversLock
+3. virNWFilterLockFilterUpdates
+4. virNWFilterObjLock
+
+Other locks:
+------------
+
+Other relevant locks to consider are related to hypervisor drivers. The
+following locking orders are good with the qemu_driver as an example:
+
+qemu_driver - qemu_domain   - filter object
+qemu_driver - filter object - qemu_domain
+
+The qemu_driver serves as a general lock for all subsequent locks to a
+qemu_domain. This works because the qemu_driver will always be locked
+for a qemu_domain, thus only one lock-sequence of either (qemu_domain,
+filter object) or (filter object, qemu_domain) can be active at any time.
+
+Reference:
+https://www.redhat.com/archives/libvir-list/2010-October/msg00152.html

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]