]> xenbits.xensource.com Git - people/pauldu/xenbus.git/commitdiff
Revert "Simplify EVTCHN Unmask" master
authorPaul Durrant <paul.durrant@citrix.com>
Fri, 20 Oct 2017 15:00:11 +0000 (16:00 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 20 Oct 2017 17:13:21 +0000 (18:13 +0100)
This reverts commit 3ad02ccc6c68e98ad9a83f340cd5787e45924ace.

include/evtchn_interface.h
include/revision.h
src/xenbus/console.c
src/xenbus/evtchn.c
src/xenbus/fdo.c
src/xenbus/store.c

index 310850bab2582584179d71a02d2008ae7509fd00..068a69734fe985a782b2626a6094cc565bb9b6e2 100644 (file)
@@ -128,18 +128,27 @@ typedef NTSTATUS
     IN  UCHAR                   Number
     );
 
+typedef VOID
+(*XENBUS_EVTCHN_UNMASK_V4)(
+    IN  PINTERFACE              Interface,
+    IN  PXENBUS_EVTCHN_CHANNEL  Channel,
+    IN  BOOLEAN                 InCallback
+    );
+
 /*! \typedef XENBUS_EVTCHN_UNMASK
     \brief Unmask an event channel
 
     \param Interface The interface header
     \param Channel The channel handle
     \param InCallback Set to TRUE if this method is invoked in context of the channel callback
+    \param Force Set to TRUE if the unmask must succeed, otherwise set to FALSE and the function will return FALSE if the unmask did not complete.
 */
-typedef VOID
+typedef BOOLEAN
 (*XENBUS_EVTCHN_UNMASK)(
     IN  PINTERFACE              Interface,
     IN  PXENBUS_EVTCHN_CHANNEL  Channel,
-    IN  BOOLEAN                 InCallback
+    IN  BOOLEAN                 InCallback,
+    IN  BOOLEAN                 Force
     );
 
 typedef VOID
@@ -250,7 +259,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V4 {
     XENBUS_EVTCHN_RELEASE   EvtchnRelease;
     XENBUS_EVTCHN_OPEN      EvtchnOpen;
     XENBUS_EVTCHN_BIND      EvtchnBind;
-    XENBUS_EVTCHN_UNMASK    EvtchnUnmask;
+    XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
     XENBUS_EVTCHN_SEND_V1   EvtchnSendVersion1;
     XENBUS_EVTCHN_TRIGGER   EvtchnTrigger;
     XENBUS_EVTCHN_GET_PORT  EvtchnGetPort;
@@ -267,7 +276,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V5 {
     XENBUS_EVTCHN_RELEASE   EvtchnRelease;
     XENBUS_EVTCHN_OPEN      EvtchnOpen;
     XENBUS_EVTCHN_BIND      EvtchnBind;
-    XENBUS_EVTCHN_UNMASK    EvtchnUnmask;
+    XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
     XENBUS_EVTCHN_SEND_V1   EvtchnSendVersion1;
     XENBUS_EVTCHN_TRIGGER   EvtchnTrigger;
     XENBUS_EVTCHN_WAIT_V5   EvtchnWaitVersion5;
@@ -285,7 +294,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V6 {
     XENBUS_EVTCHN_RELEASE   EvtchnRelease;
     XENBUS_EVTCHN_OPEN      EvtchnOpen;
     XENBUS_EVTCHN_BIND      EvtchnBind;
-    XENBUS_EVTCHN_UNMASK    EvtchnUnmask;
+    XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
     XENBUS_EVTCHN_SEND      EvtchnSend;
     XENBUS_EVTCHN_TRIGGER   EvtchnTrigger;
     XENBUS_EVTCHN_WAIT_V5   EvtchnWaitVersion5;
@@ -298,6 +307,25 @@ struct _XENBUS_EVTCHN_INTERFACE_V6 {
     \ingroup interfaces
 */
 struct _XENBUS_EVTCHN_INTERFACE_V7 {
+    INTERFACE               Interface;
+    XENBUS_EVTCHN_ACQUIRE   EvtchnAcquire;
+    XENBUS_EVTCHN_RELEASE   EvtchnRelease;
+    XENBUS_EVTCHN_OPEN      EvtchnOpen;
+    XENBUS_EVTCHN_BIND      EvtchnBind;
+    XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
+    XENBUS_EVTCHN_SEND      EvtchnSend;
+    XENBUS_EVTCHN_TRIGGER   EvtchnTrigger;
+    XENBUS_EVTCHN_GET_COUNT EvtchnGetCount;
+    XENBUS_EVTCHN_WAIT      EvtchnWait;
+    XENBUS_EVTCHN_GET_PORT  EvtchnGetPort;
+    XENBUS_EVTCHN_CLOSE     EvtchnClose;
+};
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V8
+    \brief EVTCHN interface version 8
+    \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V8 {
     INTERFACE               Interface;
     XENBUS_EVTCHN_ACQUIRE   EvtchnAcquire;
     XENBUS_EVTCHN_RELEASE   EvtchnRelease;
@@ -312,7 +340,7 @@ struct _XENBUS_EVTCHN_INTERFACE_V7 {
     XENBUS_EVTCHN_CLOSE     EvtchnClose;
 };
 
-typedef struct _XENBUS_EVTCHN_INTERFACE_V7 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE;
+typedef struct _XENBUS_EVTCHN_INTERFACE_V8 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVTCHN_INTERFACE;
 
 /*! \def XENBUS_EVTCHN
     \brief Macro at assist in method invocation
@@ -323,7 +351,7 @@ typedef struct _XENBUS_EVTCHN_INTERFACE_V7 XENBUS_EVTCHN_INTERFACE, *PXENBUS_EVT
 #endif  // _WINDLL
 
 #define XENBUS_EVTCHN_INTERFACE_VERSION_MIN 4
-#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 7
+#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 8
 
 #endif  // _XENBUS_EVTCHN_INTERFACE_H
 
index bc73be23da012240c4a0c314c0fbddcf553f3b42..6aaf88815f333f217671344b4d3f9d0542b57645 100644 (file)
@@ -52,6 +52,7 @@
     DEFINE_REVISION(0x0800000B,  1,  2,  5,  1,  2,  1,  1,  2,  1,  0,  1), \
     DEFINE_REVISION(0x09000000,  1,  2,  5,  1,  2,  1,  1,  2,  1,  0,  1), \
     DEFINE_REVISION(0x09000001,  1,  2,  6,  1,  2,  1,  1,  2,  1,  1,  1), \
-    DEFINE_REVISION(0x09000002,  1,  2,  7,  1,  2,  1,  1,  2,  1,  1,  1)
+    DEFINE_REVISION(0x09000002,  1,  2,  7,  1,  2,  1,  1,  2,  1,  1,  1), \
+    DEFINE_REVISION(0x09000003,  1,  2,  8,  1,  2,  1,  1,  2,  1,  1,  1)
 
 #endif  // _REVISION_H
index bebc6f3f2e5e71507c9400a50a1c33ff37b9b2e1..1ca25f0aaea44ff79d98d1cce8f1db3959e24f18 100644 (file)
@@ -354,10 +354,11 @@ ConsoleEnable(
                                      FALSE);
     ASSERT(Context->Channel != NULL);
 
-    XENBUS_EVTCHN(Unmask,
-                  &Context->EvtchnInterface,
-                  Context->Channel,
-                  FALSE);
+    (VOID) XENBUS_EVTCHN(Unmask,
+                         &Context->EvtchnInterface,
+                         Context->Channel,
+                         FALSE,
+                         TRUE);
 
     Context->Enabled = TRUE;
 
index 2ac192dd02e491c09b3390ab4260af40c5e04ae2..09862b0577b4dd8e97c9f22274aaa7b63f076c2e 100644 (file)
@@ -727,16 +727,19 @@ fail1:
     return status;
 }
 
-static VOID
+static BOOLEAN
 EvtchnUnmask(
     IN  PINTERFACE              Interface,
     IN  PXENBUS_EVTCHN_CHANNEL  Channel,
-    IN  BOOLEAN                 InUpcall
+    IN  BOOLEAN                 InUpcall,
+    IN  BOOLEAN                 Force
     )
 {
     PXENBUS_EVTCHN_CONTEXT      Context = Interface->Context;
     KIRQL                       Irql = PASSIVE_LEVEL;
+    BOOLEAN                     Pending;
     ULONG                       LocalPort;
+    PROCESSOR_NUMBER            ProcNumber;
 
     ASSERT3U(Channel->Magic, ==, XENBUS_EVTCHN_CHANNEL_MAGIC);
 
@@ -745,27 +748,76 @@ EvtchnUnmask(
 
     ASSERT3U(KeGetCurrentIrql(), >=, DISPATCH_LEVEL);
 
+    Pending = FALSE;
+
     if (!Channel->Active)
         goto done;
 
     LocalPort = Channel->LocalPort;
 
-    if (XENBUS_EVTCHN_ABI(PortUnmask,
+    Pending = XENBUS_EVTCHN_ABI(PortUnmask,
+                                &Context->EvtchnAbi,
+                                LocalPort);
+
+    if (!Pending)
+        goto done;
+
+    //
+    // If we are in context of the upcall, or we cannot tolerate a
+    // failure to unmask,then use the hypercall.
+    //
+    if (InUpcall || Force) {
+        XENBUS_EVTCHN_ABI(PortMask,
                           &Context->EvtchnAbi,
-                          LocalPort)) {
-        //
-        // The event was pending so we must re-mask and use
-        // a hypercall to do the unmask and raise the event
-        //
+                          LocalPort);
+        (VOID) EventChannelUnmask(LocalPort);
+
+        Pending = FALSE;
+        goto done;
+    }
+
+    //
+    // If we are not unmasking on the same CPU to which the
+    // event channel is bound, then we need to use the hypercall.
+    // to schedule the upcall on the correct CPU.
+    //
+    (VOID) KeGetCurrentProcessorNumberEx(&ProcNumber);
+
+    if (Channel->ProcNumber.Group != ProcNumber.Group ||
+        Channel->ProcNumber.Number != ProcNumber.Number) {
         XENBUS_EVTCHN_ABI(PortMask,
                           &Context->EvtchnAbi,
                           LocalPort);
         (VOID) EventChannelUnmask(LocalPort);
+
+        Pending = FALSE;
+        goto done;
     }
 
+    if (Channel->Mask)
+        XENBUS_EVTCHN_ABI(PortMask,
+                          &Context->EvtchnAbi,
+                          LocalPort);
+
+    XENBUS_EVTCHN_ABI(PortAck,
+                      &Context->EvtchnAbi,
+                      LocalPort);
+
 done:
     if (!InUpcall)
         KeReleaseSpinLock(&Channel->Lock, Irql);
+
+    return Pending;
+}
+
+static VOID
+EvtchnUnmaskVersion4(
+    IN  PINTERFACE              Interface,
+    IN  PXENBUS_EVTCHN_CHANNEL  Channel,
+    IN  BOOLEAN                 InUpcall
+    )
+{
+    EvtchnUnmask(Interface, Channel, InUpcall, TRUE);
 }
 
 static VOID
@@ -1635,7 +1687,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V4 EvtchnInterfaceVersion4 = {
     EvtchnRelease,
     EvtchnOpen,
     EvtchnBind,
-    EvtchnUnmask,
+    EvtchnUnmaskVersion4,
     EvtchnSendVersion1,
     EvtchnTrigger,
     EvtchnGetPort,
@@ -1648,7 +1700,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V5 EvtchnInterfaceVersion5 = {
     EvtchnRelease,
     EvtchnOpen,
     EvtchnBind,
-    EvtchnUnmask,
+    EvtchnUnmaskVersion4,
     EvtchnSendVersion1,
     EvtchnTrigger,
     EvtchnWaitVersion5,
@@ -1662,7 +1714,7 @@ static struct _XENBUS_EVTCHN_INTERFACE_V6 EvtchnInterfaceVersion6 = {
     EvtchnRelease,
     EvtchnOpen,
     EvtchnBind,
-    EvtchnUnmask,
+    EvtchnUnmaskVersion4,
     EvtchnSend,
     EvtchnTrigger,
     EvtchnWaitVersion5,
@@ -1676,6 +1728,21 @@ static struct _XENBUS_EVTCHN_INTERFACE_V7 EvtchnInterfaceVersion7 = {
     EvtchnRelease,
     EvtchnOpen,
     EvtchnBind,
+    EvtchnUnmaskVersion4,
+    EvtchnSend,
+    EvtchnTrigger,
+    EvtchnGetCount,
+    EvtchnWait,
+    EvtchnGetPort,
+    EvtchnClose,
+};
+
+static struct _XENBUS_EVTCHN_INTERFACE_V8 EvtchnInterfaceVersion8 = {
+    { sizeof (struct _XENBUS_EVTCHN_INTERFACE_V8), 8, NULL, NULL, NULL },
+    EvtchnAcquire,
+    EvtchnRelease,
+    EvtchnOpen,
+    EvtchnBind,
     EvtchnUnmask,
     EvtchnSend,
     EvtchnTrigger,
@@ -1861,6 +1928,23 @@ EvtchnGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 8: {
+        struct _XENBUS_EVTCHN_INTERFACE_V8  *EvtchnInterface;
+
+        EvtchnInterface = (struct _XENBUS_EVTCHN_INTERFACE_V8 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENBUS_EVTCHN_INTERFACE_V8))
+            break;
+
+        *EvtchnInterface = EvtchnInterfaceVersion8;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
index c5b5da13d4d83077406ab3eeecfb82ffc36c6b3a..7b9da12e645b5162fce8b248859b05f0ecaffa08 100644 (file)
@@ -2675,10 +2675,11 @@ __FdoD3ToD0(
     if (Fdo->Channel == NULL)
         goto fail1;
 
-    XENBUS_EVTCHN(Unmask,
-                  &Fdo->EvtchnInterface,
-                  Fdo->Channel,
-                  FALSE);
+    (VOID) XENBUS_EVTCHN(Unmask,
+                         &Fdo->EvtchnInterface,
+                         Fdo->Channel,
+                         FALSE,
+                         TRUE);
 
     status = LogAddDisposition(DriverGetConsoleLogLevel(),
                                FdoOutputBuffer,
index 101dc40259211084b600b15a4ee44b76857c9bee..0dee0547d70354db3603ecb3c1ab735300173b3d 100644 (file)
@@ -2152,10 +2152,11 @@ StoreEnable(
                                      FALSE);
     ASSERT(Context->Channel != NULL);
 
-    XENBUS_EVTCHN(Unmask,
-                  &Context->EvtchnInterface,
-                  Context->Channel,
-                  FALSE);
+    (VOID) XENBUS_EVTCHN(Unmask,
+                         &Context->EvtchnInterface,
+                         Context->Channel,
+                         FALSE,
+                         TRUE);
 
     Context->Enabled = TRUE;