]> xenbits.xensource.com Git - people/pauldu/xenvif.git/commitdiff
Make sure we don't end up with duplicate PDOs
authorPaul Durrant <paul.durrant@citrix.com>
Thu, 28 Jul 2016 09:00:51 +0000 (10:00 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 28 Jul 2016 09:39:44 +0000 (10:39 +0100)
In a tight loop of network attach/detach it's possible to end up with
duplicate PDOs because, as soon as a PDO gets set to 'missing' a new one
with the same name can be created. This leads to races in accessing the
vif areas in xenstore and things can get very confused.

This patch makes sure that a new PDO cannot be created until a previous
incarnation is in the 'deleted' state, which means there will definitely
be no conflict in interactions with xenstore.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenvif/fdo.c

index dae1ad8de6bac2f14f41ce9ffbd779c3c01a7bca..d66558651188d17bbe4585be39298157d6723d08 100644 (file)
@@ -749,7 +749,7 @@ __FdoEnumerate(
         PXENVIF_DX      Dx = CONTAINING_RECORD(ListEntry, XENVIF_DX, ListEntry);
         PXENVIF_PDO     Pdo = Dx->Pdo;
 
-        if (!PdoIsMissing(Pdo) && PdoGetDevicePnpState(Pdo) != Deleted) {
+        if (PdoGetDevicePnpState(Pdo) != Deleted) {
             PCHAR           Name;
             BOOLEAN         Missing;
 
@@ -771,20 +771,22 @@ __FdoEnumerate(
                 }
             }
 
-            if (PdoIsEjectRequested(Pdo)) {
-                IoRequestDeviceEject(PdoGetDeviceObject(Pdo));
-            } else if (Missing) {
-                PdoSetMissing(Pdo, "device disappeared");
-
-                // If the PDO has not yet been enumerated then we can
-                // go ahead and mark it as deleted, otherwise we need
-                // to notify PnP manager and wait for the REMOVE_DEVICE
-                // IRP.
-                if (PdoGetDevicePnpState(Pdo) == Present) {
-                    PdoSetDevicePnpState(Pdo, Deleted);
-                    PdoDestroy(Pdo);
-                } else {
-                    NeedInvalidate = TRUE;
+            if (!PdoIsMissing(Pdo)) {
+                if (PdoIsEjectRequested(Pdo)) {
+                    IoRequestDeviceEject(PdoGetDeviceObject(Pdo));
+                } else if (Missing) {
+                    PdoSetMissing(Pdo, "device disappeared");
+
+                    // If the PDO has not yet been enumerated then we can
+                    // go ahead and mark it as deleted, otherwise we need
+                    // to notify PnP manager and wait for the REMOVE_DEVICE
+                    // IRP.
+                    if (PdoGetDevicePnpState(Pdo) == Present) {
+                        PdoSetDevicePnpState(Pdo, Deleted);
+                        PdoDestroy(Pdo);
+                    } else {
+                        NeedInvalidate = TRUE;
+                    }
                 }
             }
         }