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

[win-pv-devel] [PATCH] Indirect user space watch events through a thread



It is useful, for diagnostic purposes, to log the path of a user-space
registered watch when we are about to signal it. To do this create a
thread to handle each user-space watch.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xeniface/ioctl_store.c | 58 ++++++++++++++++++++++++++++++++++++++++++----
 src/xeniface/ioctls.c      | 13 ++++++++++-
 src/xeniface/ioctls.h      |  2 ++
 3 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/src/xeniface/ioctl_store.c b/src/xeniface/ioctl_store.c
index 5bd4649..1725e06 100644
--- a/src/xeniface/ioctl_store.c
+++ b/src/xeniface/ioctl_store.c
@@ -428,6 +428,36 @@ fail1:
     return status;
 }
 
+static NTSTATUS
+StoreWatch(
+    IN  PXENIFACE_THREAD    Self,
+    IN  PVOID               _Context
+    )
+{
+    PXENIFACE_STORE_CONTEXT Context = _Context;
+    PKEVENT                 Event;
+
+    Event = ThreadGetEvent(Self);
+
+    for (;;) {
+        (VOID) KeWaitForSingleObject(Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        KeClearEvent(Event);
+
+        if (ThreadIsAlerted(Self))
+            break;
+
+        XenIfaceDebugPrint(INFO, "%s\n", Context->Path);
+
+        KeSetEvent(Context->Event, IO_NO_INCREMENT, FALSE);
+    }
+
+    return STATUS_SUCCESS;
+}
+
 DECLSPEC_NOINLINE
 NTSTATUS
 IoctlStoreAddWatch(
@@ -483,17 +513,21 @@ IoctlStoreAddWatch(
 
     XenIfaceDebugPrint(TRACE, "> Path '%s', Event %p, FO %p\n", Path, 
In->Event, FileObject);
 
+    Context->Path = Path;
+
+    status = ThreadCreate(StoreWatch, Context, &Context->Thread);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
     status = XENBUS_STORE(WatchAdd,
                           &Fdo->StoreInterface,
                           NULL, // prefix
-                          Path,
-                          Context->Event,
+                          Context->Path,
+                          ThreadGetEvent(Context->Thread),
                           &Context->Watch);
 
     if (!NT_SUCCESS(status))
-        goto fail6;
-
-    __FreeCapturedBuffer(Path);
+        goto fail7;
 
     ExInterlockedInsertTailList(&Fdo->StoreWatchList, &Context->Entry, 
&Fdo->StoreWatchLock);
 
@@ -504,6 +538,13 @@ IoctlStoreAddWatch(
 
     return status;
 
+fail7:
+    __FreeCapturedBuffer(Context->Path);
+
+    XenIfaceDebugPrint(ERROR, "Fail7\n");
+    ThreadAlert(Context->Thread);
+    ThreadJoin(Context->Thread);
+
 fail6:
     XenIfaceDebugPrint(ERROR, "Fail6\n");
     ObDereferenceObject(Context->Event);
@@ -537,6 +578,8 @@ StoreFreeWatch(
 {
     NTSTATUS status;
 
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
     XenIfaceDebugPrint(TRACE, "Context %p, Watch %p, FO %p\n",
                        Context, Context->Watch, Context->FileObject);
 
@@ -546,6 +589,11 @@ StoreFreeWatch(
 
     ASSERT(NT_SUCCESS(status)); // this is fatal since we'd leave an active 
watch without cleaning it up
 
+    ThreadAlert(Context->Thread);
+    ThreadJoin(Context->Thread);
+
+    __FreeCapturedBuffer(Context->Path);
+
     ObDereferenceObject(Context->Event);
     RtlZeroMemory(Context, sizeof(XENIFACE_STORE_CONTEXT));
     ExFreePoolWithTag(Context, XENIFACE_POOL_TAG);
diff --git a/src/xeniface/ioctls.c b/src/xeniface/ioctls.c
index e47ef6e..8e5648b 100644
--- a/src/xeniface/ioctls.c
+++ b/src/xeniface/ioctls.c
@@ -157,6 +157,7 @@ XenIfaceCleanup(
     LIST_ENTRY ToFree;
 
     // store watches
+    InitializeListHead(&ToFree);
     KeAcquireSpinLock(&Fdo->StoreWatchLock, &Irql);
     Node = Fdo->StoreWatchList.Flink;
     while (Node->Flink != Fdo->StoreWatchList.Flink) {
@@ -169,10 +170,20 @@ XenIfaceCleanup(
 
         XenIfaceDebugPrint(TRACE, "Store context %p\n", StoreContext);
         RemoveEntryList(&StoreContext->Entry);
-        StoreFreeWatch(Fdo, StoreContext);
+        // StoreFreeWatch requires PASSIVE_LEVEL and we're inside a lock
+        InsertTailList(&ToFree, &StoreContext->Entry);
     }
     KeReleaseSpinLock(&Fdo->StoreWatchLock, Irql);
 
+    Node = ToFree.Flink;
+    while (Node->Flink != ToFree.Flink) {
+        StoreContext = CONTAINING_RECORD(Node, XENIFACE_STORE_CONTEXT, Entry);
+        Node = Node->Flink;
+
+        RemoveEntryList(&StoreContext->Entry);
+        StoreFreeWatch(Fdo, StoreContext);
+    }
+
     // event channels
     InitializeListHead(&ToFree);
     KeAcquireSpinLock(&Fdo->EvtchnLock, &Irql);
diff --git a/src/xeniface/ioctls.h b/src/xeniface/ioctls.h
index 16af0a2..c954e9e 100644
--- a/src/xeniface/ioctls.h
+++ b/src/xeniface/ioctls.h
@@ -48,6 +48,8 @@ typedef struct _XENIFACE_CONTEXT_ID {
 
 typedef struct _XENIFACE_STORE_CONTEXT {
     LIST_ENTRY             Entry;
+    PCHAR                  Path;
+    PXENIFACE_THREAD       Thread;
     PXENBUS_STORE_WATCH    Watch;
     PKEVENT                Event;
     PVOID                  FileObject;
-- 
2.5.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.