All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony PERARD <anthony.perard@citrix.com>
To: <devel@edk2.groups.io>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Julien Grall <julien.grall@arm.com>,
	Anthony Perard <anthony.perard@citrix.com>,
	xen-devel@lists.xenproject.org, Laszlo Ersek <lersek@redhat.com>
Subject: [Xen-devel] [PATCH 03/11] OvmfPkg/XenBusDxe: Rework watch events reception
Date: Fri, 13 Sep 2019 15:50:52 +0100	[thread overview]
Message-ID: <20190913145100.303433-4-anthony.perard@citrix.com> (raw)
In-Reply-To: <20190913145100.303433-1-anthony.perard@citrix.com>

This patch rework the reception of xenstore watch event to avoid
allocation.

Instead of queuing watch events, we simply mark a XENSTORE_WATCH as
"triggered". We don't need to know how many time we received the
event, only that it happened. That avoid to allocate a
XENSTORE_MESSAGE for every watch events.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2190
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenBusDxe/XenStore.c | 125 ++++++++++-------------------------
 1 file changed, 35 insertions(+), 90 deletions(-)

diff --git a/OvmfPkg/XenBusDxe/XenStore.c b/OvmfPkg/XenBusDxe/XenStore.c
index 727641a0fe..5cc900190a 100644
--- a/OvmfPkg/XenBusDxe/XenStore.c
+++ b/OvmfPkg/XenBusDxe/XenStore.c
@@ -65,6 +65,8 @@ struct _XENSTORE_WATCH
 
   /* Path being watched. */
   CHAR8       *Node;
+
+  BOOLEAN     Triggered;
 };
 
 #define XENSTORE_WATCH_FROM_LINK(l) \
@@ -86,13 +88,6 @@ typedef struct {
     struct {
       CHAR8 *Body;
     } Reply;
-
-    /* Queued watch events. */
-    struct {
-      XENSTORE_WATCH *Handle;
-      CONST CHAR8 **Vector;
-      UINT32 VectorSize;
-    } Watch;
   } u;
 } XENSTORE_MESSAGE;
 #define XENSTORE_MESSAGE_FROM_LINK(r) \
@@ -133,14 +128,6 @@ typedef struct {
   /** Lock protecting the registered watches list. */
   EFI_LOCK RegisteredWatchesLock;
 
-  /**
-   * List of pending watch callback events.
-   */
-  LIST_ENTRY WatchEvents;
-
-  /** Lock protecting the watch calback list. */
-  EFI_LOCK WatchEventsLock;
-
   /**
    * The event channel for communicating with the
    * XenStore service.
@@ -630,29 +617,32 @@ XenStoreProcessMessage (
   Body[Message->Header.len] = '\0';
 
   if (Message->Header.type == XS_WATCH_EVENT) {
-    VOID *ConvertedToken;
+    CONST CHAR8    *WatchEventPath;
+    CONST CHAR8    *WatchEventToken;
+    VOID           *ConvertedToken;
+    XENSTORE_WATCH *Watch;
 
-    Message->u.Watch.Vector = Split(Body, Message->Header.len,
-                                    &Message->u.Watch.VectorSize);
+    //
+    // Parse WATCH_EVENT messages
+    //   <path>\0<token>\0
+    //
+    WatchEventPath = Body;
+    WatchEventToken = WatchEventPath + AsciiStrSize (WatchEventPath);
 
-    ConvertedToken =
-      (VOID *) AsciiStrHexToUintn (Message->u.Watch.Vector[XS_WATCH_TOKEN]);
+    ConvertedToken = (VOID *) AsciiStrHexToUintn (WatchEventToken);
 
     EfiAcquireLock (&xs.RegisteredWatchesLock);
-    Message->u.Watch.Handle = XenStoreFindWatch (ConvertedToken);
-    DEBUG ((EFI_D_INFO, "XenStore: Watch event %a\n",
-            Message->u.Watch.Vector[XS_WATCH_TOKEN]));
-    if (Message->u.Watch.Handle != NULL) {
-      EfiAcquireLock (&xs.WatchEventsLock);
-      InsertHeadList (&xs.WatchEvents, &Message->Link);
-      EfiReleaseLock (&xs.WatchEventsLock);
+    Watch = XenStoreFindWatch (ConvertedToken);
+    DEBUG ((DEBUG_INFO, "XenStore: Watch event %a\n", WatchEventToken));
+    if (Watch != NULL) {
+      Watch->Triggered = TRUE;
     } else {
       DEBUG ((EFI_D_WARN, "XenStore: Watch handle %a not found\n",
-              Message->u.Watch.Vector[XS_WATCH_TOKEN]));
-      FreePool((VOID*)Message->u.Watch.Vector);
-      FreePool(Message);
+              WatchEventToken));
     }
     EfiReleaseLock (&xs.RegisteredWatchesLock);
+    FreePool (Message);
+    FreePool (Body);
   } else {
     Message->u.Reply.Body = Body;
     EfiAcquireLock (&xs.ReplyLock);
@@ -936,40 +926,29 @@ XenStoreUnwatch (
 STATIC
 XENSTORE_STATUS
 XenStoreWaitWatch (
-  VOID *Token
+  IN VOID *Token
   )
 {
-  XENSTORE_MESSAGE *Message;
-  LIST_ENTRY *Entry = NULL;
-  LIST_ENTRY *Last = NULL;
+  XENSTORE_WATCH  *Watch;
   XENSTORE_STATUS Status;
 
+  EfiAcquireLock (&xs.RegisteredWatchesLock);
+  Watch = XenStoreFindWatch (Token);
+  EfiReleaseLock (&xs.RegisteredWatchesLock);
+  if (Watch == NULL) {
+    return XENSTORE_STATUS_EINVAL;
+  }
+
   while (TRUE) {
-    EfiAcquireLock (&xs.WatchEventsLock);
-    if (IsListEmpty (&xs.WatchEvents) ||
-        Last == GetFirstNode (&xs.WatchEvents)) {
-      EfiReleaseLock (&xs.WatchEventsLock);
-      Status = XenStoreProcessMessage ();
-      if (Status != XENSTORE_STATUS_SUCCESS && Status != XENSTORE_STATUS_EAGAIN) {
-        return Status;
-      }
-      continue;
+    if (Watch->Triggered) {
+      Watch->Triggered = FALSE;
+      return XENSTORE_STATUS_SUCCESS;
     }
 
-    for (Entry = GetFirstNode (&xs.WatchEvents);
-         Entry != Last && !IsNull (&xs.WatchEvents, Entry);
-         Entry = GetNextNode (&xs.WatchEvents, Entry)) {
-      Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
-      if (Message->u.Watch.Handle == Token) {
-        RemoveEntryList (Entry);
-        EfiReleaseLock (&xs.WatchEventsLock);
-        FreePool((VOID*)Message->u.Watch.Vector);
-        FreePool(Message);
-        return XENSTORE_STATUS_SUCCESS;
-      }
+    Status = XenStoreProcessMessage ();
+    if (Status != XENSTORE_STATUS_SUCCESS && Status != XENSTORE_STATUS_EAGAIN) {
+      return Status;
     }
-    Last = GetFirstNode (&xs.WatchEvents);
-    EfiReleaseLock (&xs.WatchEventsLock);
   }
 }
 
@@ -1052,12 +1031,10 @@ XenStoreInit (
           xs.XenStore, xs.EventChannel));
 
   InitializeListHead (&xs.ReplyList);
-  InitializeListHead (&xs.WatchEvents);
   InitializeListHead (&xs.RegisteredWatches);
 
   EfiInitializeLock (&xs.ReplyLock, TPL_NOTIFY);
   EfiInitializeLock (&xs.RegisteredWatchesLock, TPL_NOTIFY);
-  EfiInitializeLock (&xs.WatchEventsLock, TPL_NOTIFY);
 
   /* Initialize the shared memory rings to talk to xenstored */
   Status = XenStoreInitComms (&xs);
@@ -1088,23 +1065,6 @@ XenStoreDeinit (
     }
   }
 
-  //
-  // Emptying the list WatchEvents, but this list should already be empty after
-  // having cleanup the list RegisteredWatches.
-  //
-  if (!IsListEmpty (&xs.WatchEvents)) {
-    LIST_ENTRY *Entry;
-    DEBUG ((DEBUG_WARN, "XenStore: WatchEvents is not empty, cleaning up...\n"));
-    Entry = GetFirstNode (&xs.WatchEvents);
-    while (!IsNull (&xs.WatchEvents, Entry)) {
-      XENSTORE_MESSAGE *Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
-      Entry = GetNextNode (&xs.WatchEvents, Entry);
-      RemoveEntryList (&Message->Link);
-      FreePool ((VOID*)Message->u.Watch.Vector);
-      FreePool (Message);
-    }
-  }
-
   if (!IsListEmpty (&xs.ReplyList)) {
     XENSTORE_MESSAGE *Message;
     LIST_ENTRY *Entry;
@@ -1382,7 +1342,6 @@ XenStoreUnregisterWatch (
   )
 {
   CHAR8 Token[sizeof (Watch) * 2 + 1];
-  LIST_ENTRY *Entry;
 
   ASSERT (Watch->Signature == XENSTORE_WATCH_SIGNATURE);
 
@@ -1397,20 +1356,6 @@ XenStoreUnregisterWatch (
   AsciiSPrint (Token, sizeof (Token), "%p", (VOID *) Watch);
   XenStoreUnwatch (Watch->Node, Token);
 
-  /* Cancel pending watch events. */
-  EfiAcquireLock (&xs.WatchEventsLock);
-  Entry = GetFirstNode (&xs.WatchEvents);
-  while (!IsNull (&xs.WatchEvents, Entry)) {
-    XENSTORE_MESSAGE *Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
-    Entry = GetNextNode (&xs.WatchEvents, Entry);
-    if (Message->u.Watch.Handle == Watch) {
-      RemoveEntryList (&Message->Link);
-      FreePool ((VOID*)Message->u.Watch.Vector);
-      FreePool (Message);
-    }
-  }
-  EfiReleaseLock (&xs.WatchEventsLock);
-
   FreePool (Watch->Node);
   FreePool (Watch);
 }
-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-09-13 14:51 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-13 14:50 [Xen-devel] [PATCH 00/11] OvmfPkg/XenBusDxe: Fix ExitBootServices handler to avoid allocation Anthony PERARD
2019-09-13 14:50 ` [Xen-devel] [PATCH 01/11] OvmfPkg/XenBusDxe: Fix missing \n in DEBUG messages Anthony PERARD
2019-09-16 14:24   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 02/11] OvmfPkg/XenBusDxe: Have XenStoreFindWatch take a pointer Anthony PERARD
2019-09-16 14:38   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-13 14:50 ` Anthony PERARD [this message]
2019-09-16 14:39   ` [Xen-devel] [edk2-devel] [PATCH 03/11] OvmfPkg/XenBusDxe: Rework watch events reception Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 04/11] OvmfPkg/XenBusDxe: Avoid Allocate in XenStoreVSPrint Anthony PERARD
2019-09-16 14:45   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 05/11] OvmfPkg/XenBusDxe: Construct paths without allocation Anthony PERARD
2019-09-16 15:39   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-16 15:43     ` Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 06/11] OvmfPkg/XenBusDxe: Rework XenStoreProcessMessage to avoid allocating memory Anthony PERARD
2019-09-16 15:41   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 07/11] OvmfPkg/XenBusDxe: Use on stack buffer in internal functions Anthony PERARD
2019-09-16 16:11   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 08/11] OvmfPkg/XenBus: Change XENBUS_PROTOCOL to not return allocated memory Anthony PERARD
2019-09-16 16:16   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-13 14:50 ` [Xen-devel] [PATCH 09/11] OvmfPkg/XenBusDxe: Fix NotifyExitBoot to avoid Memory Allocation Services Anthony PERARD
2019-09-16 17:36   ` [Xen-devel] [edk2-devel] " Laszlo Ersek
2019-09-16 18:36     ` Andrew Fish
2019-09-16 19:31       ` Laszlo Ersek
2019-09-16 20:50         ` Andrew Fish
2019-09-13 14:50 ` [Xen-devel] [PATCH 10/11] OvmfPkg/XenPvBlkDxe: Use XenBusIo->RegisterExitCallback Anthony PERARD
2019-09-13 14:51 ` [Xen-devel] [PATCH 11/11] OvmfPkg/XenBusDxe: Fix XenStoreWaitForEvent use during EBS Anthony PERARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190913145100.303433-4-anthony.perard@citrix.com \
    --to=anthony.perard@citrix.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=devel@edk2.groups.io \
    --cc=jordan.l.justen@intel.com \
    --cc=julien.grall@arm.com \
    --cc=lersek@redhat.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.