[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH RESEND v6 12/36] multi-process: add functions to synchronize prox
From: |
elena . ufimtseva |
Subject: |
[PATCH RESEND v6 12/36] multi-process: add functions to synchronize proxy and remote endpoints |
Date: |
Wed, 22 Apr 2020 21:13:47 -0700 |
From: Jagannathan Raman <address@hidden>
In some cases, for example MMIO read, QEMU has to wait for the remote to
complete a command before proceeding. An eventfd based mechanism is
added to synchronize QEMU & remote process.
Signed-off-by: John G Johnson <address@hidden>
Signed-off-by: Jagannathan Raman <address@hidden>
Signed-off-by: Elena Ufimtseva <address@hidden>
---
include/io/mpqemu-link.h | 7 +++++
io/mpqemu-link.c | 61 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)
diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
index af401e640c..ef95599bca 100644
--- a/include/io/mpqemu-link.h
+++ b/include/io/mpqemu-link.h
@@ -124,4 +124,11 @@ void mpqemu_link_set_callback(MPQemuLinkState *s,
void mpqemu_start_coms(MPQemuLinkState *s, MPQemuChannel* chan);
bool mpqemu_msg_valid(MPQemuMsg *msg);
+#define GET_REMOTE_WAIT eventfd(0, EFD_CLOEXEC)
+#define PUT_REMOTE_WAIT(wait) close(wait)
+#define PROXY_LINK_WAIT_DONE 1
+
+uint64_t wait_for_remote(int efd);
+void notify_proxy(int fd, uint64_t val);
+
#endif
diff --git a/io/mpqemu-link.c b/io/mpqemu-link.c
index 48f53a8928..cc0a7aecd4 100644
--- a/io/mpqemu-link.c
+++ b/io/mpqemu-link.c
@@ -10,6 +10,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include <poll.h>
#include "qemu/module.h"
#include "io/mpqemu-link.h"
@@ -204,6 +205,66 @@ int mpqemu_msg_recv(MPQemuMsg *msg, MPQemuChannel *chan)
return rc;
}
+/*
+ * wait_for_remote() Synchronizes QEMU and the remote process. The maximum
+ * wait time is 1s, after which the wait times out.
+ * The function alse returns a 64 bit return value after
+ * the wait. The function uses eventfd() to do the wait
+ * and pass the return values. eventfd() can't return a
+ * value of '0'. Therefore, all return values are offset
+ * by '1' at the sending end, and corrected at the
+ * receiving end.
+ */
+
+uint64_t wait_for_remote(int efd)
+{
+ struct pollfd pfd = { .fd = efd, .events = POLLIN };
+ uint64_t val;
+ int ret;
+
+ ret = poll(&pfd, 1, 1000);
+
+ switch (ret) {
+ case 0:
+ qemu_log_mask(LOG_REMOTE_DEBUG, "Error wait_for_remote: Timed out\n");
+ /* TODO: Kick-off error recovery */
+ return UINT64_MAX;
+ case -1:
+ qemu_log_mask(LOG_REMOTE_DEBUG, "Poll error wait_for_remote: %s\n",
+ strerror(errno));
+ return UINT64_MAX;
+ default:
+ if (read(efd, &val, sizeof(val)) == -1) {
+ qemu_log_mask(LOG_REMOTE_DEBUG, "Error wait_for_remote: %s\n",
+ strerror(errno));
+ return UINT64_MAX;
+ }
+ }
+
+ /*
+ * The remote process could write a non-zero value
+ * to the eventfd to wake QEMU up. However, the drawback of using eventfd
+ * for this purpose is that a return value of zero wouldn't wake QEMU up.
+ * Therefore, we offset the return value by one at the remote process and
+ * correct it in the QEMU end.
+ */
+ val = (val == UINT64_MAX) ? val : (val - 1);
+
+ return val;
+}
+
+void notify_proxy(int efd, uint64_t val)
+{
+ val = (val == UINT64_MAX) ? val : (val + 1);
+ ssize_t len = -1;
+
+ len = write(efd, &val, sizeof(val));
+ if (len == -1 || len != sizeof(val)) {
+ qemu_log_mask(LOG_REMOTE_DEBUG, "Error notify_proxy: %s\n",
+ strerror(errno));
+ }
+}
+
static gboolean mpqemu_link_handler_prepare(GSource *gsrc, gint *timeout)
{
g_assert(timeout);
--
2.25.GIT
- [PATCH RESEND v6 30/36] multi-process: perform device reset in the remote process, (continued)
- [PATCH RESEND v6 30/36] multi-process: perform device reset in the remote process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 31/36] multi-process/mon: choose HMP commands based on target, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 34/36] multi-process/mon: Initialize QMP module for remote processes, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 32/36] multi-process/mon: stub functions to enable QMP module for remote process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 35/36] multi-process: add the concept description to docs/devel/qemu-multiprocess, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 02/36] multi-process: Refactor machine_init and exit notifiers, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 08/36] multi-process: Add stub functions to facilitate build of multi-process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 10/36] multi-process: build system for remote device process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 11/36] multi-process: define mpqemu-link object, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 12/36] multi-process: add functions to synchronize proxy and remote endpoints,
elena . ufimtseva <=
- [PATCH RESEND v6 14/36] multi-process: setup a machine object for remote device process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 17/36] multi-process: introduce proxy object, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 24/36] multi-process: Retrieve PCI info from remote process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 26/36] multi-process: add parse_cmdline in remote process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 28/36] multi-process: send heartbeat messages to remote, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 33/36] multi-process/mon: enable QMP module support in the remote process, elena . ufimtseva, 2020/04/23
- [PATCH RESEND v6 36/36] multi-process: add configure and usage information, elena . ufimtseva, 2020/04/23