]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Enable and disable callback via at source rather than
authorPaul Durrant <paul.durrant@citrix.com>
Fri, 1 Nov 2013 09:21:42 +0000 (10:21 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 1 Nov 2013 09:21:42 +0000 (10:21 +0100)
trying to keep a local disabled flag for the interrupt.
If we don't do this we can get into a interrupt storm on
startup.

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

index 7dda022ea7a0f0ef24ddcbbefe73e9839c4a4f63..014d1a354e07b4a830be02ccb6b3e49cd2a21d9f 100644 (file)
@@ -87,6 +87,7 @@ struct _XENBUS_EVTCHN_CONTEXT {
     LONG                            References;
     PXENBUS_RESOURCE                Interrupt;
     PKINTERRUPT                     InterruptObject;
+    BOOLEAN                         Enabled;
     PXENBUS_SUSPEND_INTERFACE       SuspendInterface;
     PXENBUS_SUSPEND_CALLBACK        SuspendCallbackEarly;
     PXENBUS_DEBUG_INTERFACE         DebugInterface;
@@ -646,6 +647,31 @@ EvtchnInterrupt(
                        Context);
 }
 
+static FORCEINLINE VOID
+__EvtchnInterruptEnable(
+    IN  PXENBUS_EVTCHN_CONTEXT  Context
+    )
+{
+    NTSTATUS                    status;
+
+    status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ,
+                         Context->Interrupt->Raw.u.Interrupt.Vector);
+    ASSERT(NT_SUCCESS(status));
+}
+
+static FORCEINLINE VOID
+__EvtchnInterruptDisable(
+    IN  PXENBUS_EVTCHN_CONTEXT  Context
+    )
+{
+    NTSTATUS                    status;
+
+    UNREFERENCED_PARAMETER(Context);
+
+    status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ, 0);
+    ASSERT(NT_SUCCESS(status));
+}
+
 static VOID
 EvtchnSuspendCallbackEarly(
     IN  PVOID                   Argument
@@ -653,7 +679,6 @@ EvtchnSuspendCallbackEarly(
 {
     PXENBUS_EVTCHN_CONTEXT      Context = Argument;
     PLIST_ENTRY                 ListEntry;
-    NTSTATUS                    status;
 
     for (ListEntry = Context->List.Flink;
          ListEntry != &Context->List;
@@ -672,8 +697,8 @@ EvtchnSuspendCallbackEarly(
         }
     }
 
-    status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ, Context->Interrupt->Raw.u.Interrupt.Vector);
-    ASSERT(NT_SUCCESS(status));
+    if (Context->Enabled)
+        __EvtchnInterruptEnable(Context);
 }
 
 static VOID
@@ -793,9 +818,6 @@ EvtchnInitialize(
     Context->Interrupt = FdoGetResource(Fdo, INTERRUPT_RESOURCE);
     Context->InterruptObject = FdoGetInterruptObject(Fdo);
 
-    status = HvmSetParam(HVM_PARAM_CALLBACK_IRQ, Context->Interrupt->Raw.u.Interrupt.Vector);
-    ASSERT(NT_SUCCESS(status));
-
     Context->SuspendInterface = FdoGetSuspendInterface(Fdo);
 
     SUSPEND(Acquire, Context->SuspendInterface);
@@ -864,6 +886,32 @@ fail1:
     return status;
 }
 
+VOID
+EvtchnEnable(
+    IN PXENBUS_EVTCHN_INTERFACE Interface
+    )
+{
+    PXENBUS_EVTCHN_CONTEXT      Context = Interface->Context;
+
+    ASSERT(!Context->Enabled);
+
+    __EvtchnInterruptEnable(Context);
+    Context->Enabled = TRUE;
+}
+
+VOID
+EvtchnDisable(
+    IN PXENBUS_EVTCHN_INTERFACE Interface
+    )
+{
+    PXENBUS_EVTCHN_CONTEXT      Context = Interface->Context;
+
+    ASSERT(Context->Enabled);
+
+    Context->Enabled = FALSE;
+    __EvtchnInterruptDisable(Context);
+}
+
 VOID
 EvtchnTeardown(
     IN OUT  PXENBUS_EVTCHN_INTERFACE    Interface
@@ -892,7 +940,6 @@ EvtchnTeardown(
     SUSPEND(Release, Context->SuspendInterface);
     Context->SuspendInterface = NULL;
 
-    (VOID) HvmSetParam(HVM_PARAM_CALLBACK_IRQ, 0);
     Context->InterruptObject = NULL;
     Context->Interrupt = NULL;
 
index ff6de3fb2f147f8c686f0da994a05dcdb6c10d47..21aec1d4a8058bbbde0716caeb8373c018cf8876 100644 (file)
@@ -57,6 +57,16 @@ EvtchnInterrupt(
     IN  PXENBUS_EVTCHN_INTERFACE    Interface
     );
 
+extern VOID
+EvtchnEnable(
+    IN  PXENBUS_EVTCHN_INTERFACE    Interface
+    );
+
+extern VOID
+EvtchnDisable(
+    IN  PXENBUS_EVTCHN_INTERFACE    Interface
+    );
+
 extern VOID
 EvtchnTeardown(
     IN OUT  PXENBUS_EVTCHN_INTERFACE    Interface
index 2805d85dafc2562c3331e1b26acfb5c573576db8..6e5c28c82abb40c406e85901b0d2eb12bc7a81fc 100644 (file)
@@ -89,7 +89,6 @@ struct _XENBUS_FDO {
 
     XENBUS_RESOURCE                 Resource[RESOURCE_COUNT];
     PKINTERRUPT                     InterruptObject;
-    BOOLEAN                         InterruptEnabled;
 
     XENBUS_SUSPEND_INTERFACE        SuspendInterface;
     XENBUS_SHARED_INFO_INTERFACE    SharedInfoInterface;
@@ -118,34 +117,6 @@ __FdoFree(
     __FreePoolWithTag(Buffer, FDO_TAG);
 }
 
-#pragma warning(push)
-#pragma warning(disable: 28230)
-#pragma warning(disable: 28285)
-
-_IRQL_requires_max_(HIGH_LEVEL) // HIGH_LEVEL is best approximation of DIRQL
-_IRQL_saves_
-_IRQL_raises_(HIGH_LEVEL) // HIGH_LEVEL is best approximation of DIRQL
-static FORCEINLINE KIRQL
-__AcquireInterruptLock(
-    _Inout_ PKINTERRUPT             Interrupt
-    )
-{
-    return KeAcquireInterruptSpinLock(Interrupt);
-}
-
-_IRQL_requires_(HIGH_LEVEL) // HIGH_LEVEL is best approximation of DIRQL
-static FORCEINLINE VOID
-__ReleaseInterruptLock(
-    _Inout_ PKINTERRUPT             Interrupt,
-    _In_ _IRQL_restores_ KIRQL      Irql
-    )
-{
-#pragma prefast(suppress:28121) // The function is not permitted to be called at the current IRQ level
-    KeReleaseInterruptSpinLock(Interrupt, Irql);
-}
-
-#pragma warning(pop)
-
 static FORCEINLINE VOID
 __FdoSetDevicePnpState(
     IN  PXENBUS_FDO         Fdo,
@@ -1239,15 +1210,15 @@ FdoInterrupt(
     )
 {
     PXENBUS_FDO             Fdo = Context;
+    BOOLEAN                 DoneSomething;
 
     UNREFERENCED_PARAMETER(InterruptObject);
 
     ASSERT(Fdo != NULL);
 
-    if (!Fdo->InterruptEnabled)
-        return FALSE;
+    DoneSomething = EvtchnInterrupt(&Fdo->EvtchnInterface);
 
-    return EvtchnInterrupt(&Fdo->EvtchnInterface);
+    return DoneSomething;
 }
 
 static FORCEINLINE VOID
@@ -1334,38 +1305,6 @@ FdoDisconnectInterrupt(
     IoDisconnectInterruptEx(&Disconnect);
 }
 
-static FORCEINLINE VOID
-__FdoEnableInterrupt(
-    IN  PXENBUS_FDO Fdo
-    )
-{
-    PKINTERRUPT     InterruptObject;
-    KIRQL           Irql;
-
-    InterruptObject = __FdoGetInterruptObject(Fdo);
-
-    Irql = __AcquireInterruptLock(InterruptObject);
-    Fdo->InterruptEnabled = TRUE;
-
-    __ReleaseInterruptLock(InterruptObject, Irql);
-}
-    
-static FORCEINLINE VOID
-__FdoDisableInterrupt(
-    IN  PXENBUS_FDO Fdo
-    )
-{
-    PKINTERRUPT     InterruptObject;
-    KIRQL           Irql;
-
-    InterruptObject = __FdoGetInterruptObject(Fdo);
-
-    Irql = __AcquireInterruptLock(InterruptObject);
-    Fdo->InterruptEnabled = FALSE;
-
-    __ReleaseInterruptLock(InterruptObject, Irql);
-}
-
 PXENBUS_DEBUG_INTERFACE
 FdoGetDebugInterface(
     IN  PXENBUS_FDO     Fdo
@@ -1843,7 +1782,7 @@ FdoS4ToS3(
 
     __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
 
-    __FdoEnableInterrupt(Fdo);
+    EvtchnEnable(&Fdo->EvtchnInterface);
 
     KeLowerIrql(Irql);
 
@@ -1894,7 +1833,7 @@ FdoS3ToS4(
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
     ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemSleeping3);
 
-    __FdoDisableInterrupt(Fdo);
+    EvtchnDisable(&Fdo->EvtchnInterface);
 
     __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);