[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 32/50] multi-process: Use separate MMIO communication channel
From: |
Jagannathan Raman |
Subject: |
[PATCH v5 32/50] multi-process: Use separate MMIO communication channel |
Date: |
Mon, 24 Feb 2020 15:55:23 -0500 |
Using a separate communication channel for MMIO helps
with improving Performance
Signed-off-by: Elena Ufimtseva <address@hidden>
Signed-off-by: Jagannathan Raman <address@hidden>
Signed-off-by: John G Johnson <address@hidden>
---
hw/proxy/qemu-proxy.c | 51 ++++++++++++++++++++++++++++---------------
include/hw/proxy/qemu-proxy.h | 1 +
include/io/mpqemu-link.h | 7 ++++++
io/mpqemu-link.c | 2 ++
qdev-monitor.c | 1 +
remote/remote-main.c | 18 ++++++++++-----
6 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index bcb24f7..68517aa 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -283,13 +283,14 @@ static int remote_spawn(PCIProxyDev *pdev, const char
*opts,
const char *exec_name, Error **errp)
{
pid_t rpid;
- int fd[2] = {-1, -1};
+ int fd[2], mmio[2];
Error *local_error = NULL;
char *argv[64];
int argc = 0;
char *sfd;
char *exec_dir;
int rc = -EINVAL;
+ struct timeval timeout = {.tv_sec = 10, .tv_usec = 0};
if (pdev->managed) {
/* Child is forked by external program (such as libvirt). */
@@ -302,7 +303,8 @@ static int remote_spawn(PCIProxyDev *pdev, const char *opts,
return rc;
}
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) ||
+ socketpair(AF_UNIX, SOCK_STREAM, 0, mmio)) {
error_setg(errp, "Unable to create unix socket.");
return rc;
}
@@ -310,6 +312,8 @@ static int remote_spawn(PCIProxyDev *pdev, const char *opts,
argc = add_argv(exec_dir, argv, argc);
sfd = g_strdup_printf("%d", fd[1]);
argc = add_argv(sfd, argv, argc);
+ sfd = g_strdup_printf("%d", mmio[1]);
+ argc = add_argv(sfd, argv, argc);
argc = make_argv((char *)opts, argv, argc);
/* TODO: Restrict the forked process' permissions and capabilities. */
@@ -318,24 +322,35 @@ static int remote_spawn(PCIProxyDev *pdev, const char
*opts,
if (rpid == -1) {
error_setg(errp, "Unable to spawn emulation program.");
close(fd[0]);
- goto fail;
+ close(fd[1]);
+ close(mmio[0]);
+ close(mmio[1]);
+ return rc;
}
if (rpid == 0) {
close(fd[0]);
+ close(mmio[0]);
rc = execv(argv[0], (char *const *)argv);
exit(1);
}
pdev->remote_pid = rpid;
pdev->socket = fd[0];
+ pdev->mmio_sock = mmio[0];
- rc = 0;
+ rc = setsockopt(mmio[0], SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
+ sizeof(timeout));
+ if (rc < 0) {
+ close(fd[0]);
+ close(mmio[0]);
-fail:
- close(fd[1]);
+ error_setg(errp, "Unable to set timeout for socket");
- return rc;
+ return rc;
+ }
+
+ return 0;
}
static int get_proxy_sock(PCIDevice *dev)
@@ -523,6 +538,9 @@ static void init_proxy(PCIDevice *dev, char *command, char
*exec_name,
mpqemu_init_channel(pdev->mpqemu_link, &pdev->mpqemu_link->com,
pdev->socket);
+ mpqemu_init_channel(pdev->mpqemu_link, &pdev->mpqemu_link->mmio,
+ pdev->mmio_sock);
+
configure_memory_sync(pdev->sync, pdev->mpqemu_link);
}
@@ -575,10 +593,10 @@ static void send_bar_access_msg(PCIProxyDev *dev,
MemoryRegion *mr,
unsigned size, bool memory)
{
MPQemuLinkState *mpqemu_link = dev->mpqemu_link;
- MPQemuMsg msg;
- int wait;
+ MPQemuMsg msg, ret;
memset(&msg, 0, sizeof(MPQemuMsg));
+ memset(&ret, 0, sizeof(MPQemuMsg));
msg.bytestream = 0;
msg.size = sizeof(msg.data1);
@@ -590,19 +608,18 @@ static void send_bar_access_msg(PCIProxyDev *dev,
MemoryRegion *mr,
msg.cmd = BAR_WRITE;
msg.data1.bar_access.val = *val;
} else {
- wait = GET_REMOTE_WAIT;
-
msg.cmd = BAR_READ;
- msg.num_fds = 1;
- msg.fds[0] = wait;
}
- mpqemu_msg_send(&msg, mpqemu_link->com);
+ mpqemu_msg_send(&msg, mpqemu_link->mmio);
- if (!write) {
- *val = wait_for_remote(wait);
- PUT_REMOTE_WAIT(wait);
+ if (write) {
+ return;
}
+
+ mpqemu_msg_recv(&ret, mpqemu_link->mmio);
+
+ *val = ret.data1.mmio_ret.val;
}
void proxy_default_bar_write(void *opaque, hwaddr addr, uint64_t val,
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index f7666fb..2a2c732 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -58,6 +58,7 @@ struct PCIProxyDev {
EventNotifier en_ping;
int socket;
+ int mmio_sock;
char *rid;
char *dev_id;
diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
index aaaf1a4..3962630 100644
--- a/include/io/mpqemu-link.h
+++ b/include/io/mpqemu-link.h
@@ -61,6 +61,7 @@ typedef enum {
GET_PCI_INFO,
RET_PCI_INFO,
PROXY_PING,
+ MMIO_RETURN,
MAX,
} mpqemu_cmd_t;
@@ -107,6 +108,10 @@ typedef struct {
} ret_pci_info_msg_t;
typedef struct {
+ uint64_t val;
+} mmio_ret_msg_t;
+
+typedef struct {
mpqemu_cmd_t cmd;
int bytestream;
size_t size;
@@ -117,6 +122,7 @@ typedef struct {
bar_access_msg_t bar_access;
set_irqfd_msg_t set_irqfd;
ret_pci_info_msg_t ret_pci_info;
+ mmio_ret_msg_t mmio_ret;
} data1;
int fds[REMOTE_MAX_FDS];
@@ -171,6 +177,7 @@ typedef struct MPQemuLinkState {
GMainLoop *loop;
MPQemuChannel *com;
+ MPQemuChannel *mmio;
mpqemu_link_callback callback;
} MPQemuLinkState;
diff --git a/io/mpqemu-link.c b/io/mpqemu-link.c
index 73b7032..07a9be9 100644
--- a/io/mpqemu-link.c
+++ b/io/mpqemu-link.c
@@ -57,6 +57,7 @@ void mpqemu_link_finalize(MPQemuLinkState *s)
g_main_loop_quit(s->loop);
mpqemu_destroy_channel(s->com);
+ mpqemu_destroy_channel(s->mmio);
object_unref(OBJECT(s));
}
@@ -330,6 +331,7 @@ void mpqemu_start_coms(MPQemuLinkState *s)
{
g_assert(g_source_attach(&s->com->gsrc, s->ctx));
+ g_assert(g_source_attach(&s->mmio->gsrc, s->ctx));
g_main_loop_run(s->loop);
}
diff --git a/qdev-monitor.c b/qdev-monitor.c
index ccd2ce0..27b2ddc 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -730,6 +730,7 @@ DeviceState *qdev_proxy_add(const char *rid, const char
*id, char *bus,
pdev->rid = g_strdup(rid);
if (old_pdev) {
pdev->socket = old_pdev->socket;
+ pdev->mmio_sock = old_pdev->mmio_sock;
pdev->remote_pid = old_pdev->remote_pid;
} else {
pdev->socket = managed ? socket : -1;
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 2c05d20..6cfc446 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -104,8 +104,8 @@ static void process_bar_write(MPQemuMsg *msg, Error **errp)
static void process_bar_read(MPQemuMsg *msg, Error **errp)
{
bar_access_msg_t *bar_access = &msg->data1.bar_access;
+ MPQemuMsg ret = { 0 };
AddressSpace *as;
- int wait = msg->fds[0];
MemTxResult res;
uint64_t val = 0;
@@ -139,9 +139,10 @@ static void process_bar_read(MPQemuMsg *msg, Error **errp)
}
fail:
- notify_proxy(wait, val);
-
- PUT_REMOTE_WAIT(wait);
+ ret.cmd = MMIO_RETURN;
+ ret.data1.mmio_ret.val = val;
+ ret.size = sizeof(ret.data1);
+ mpqemu_msg_send(&ret, mpqemu_link->mmio);
}
static void process_get_pci_info_msg(PCIDevice *pci_dev, MPQemuMsg *msg)
@@ -456,7 +457,14 @@ int main(int argc, char *argv[])
mpqemu_init_channel(mpqemu_link, &mpqemu_link->com, fd);
- parse_cmdline(argc - 2, argv + 2, NULL);
+ fd = qemu_parse_fd(argv[2]);
+ if (fd == -1) {
+ printf("Failed to parse fd for remote process.\n");
+ return -EINVAL;
+ }
+ mpqemu_init_channel(mpqemu_link, &mpqemu_link->mmio, fd);
+
+ parse_cmdline(argc - 3, argv + 3, NULL);
mpqemu_link_set_callback(mpqemu_link, process_msg);
--
1.8.3.1
- [PATCH v5 19/50] multi-process: Retrieve PCI info from remote process, (continued)
- [PATCH v5 19/50] multi-process: Retrieve PCI info from remote process, Jagannathan Raman, 2020/02/24
- [PATCH v5 21/50] multi-process: remote: add setup_devices msg processing, Jagannathan Raman, 2020/02/24
- [PATCH v5 23/50] multi-process: remote: add create_done condition, Jagannathan Raman, 2020/02/24
- [PATCH v5 25/50] multi-process: Introduce build flags to separate remote process code, Jagannathan Raman, 2020/02/24
- [PATCH v5 24/50] multi-process: add processing of remote device command line, Jagannathan Raman, 2020/02/24
- [PATCH v5 26/50] multi-process: refractor vl.c code, Jagannathan Raman, 2020/02/24
- [PATCH v5 22/50] multi-process: remote: use fd for socket from parent process, Jagannathan Raman, 2020/02/24
- [PATCH v5 27/50] multi-process: add remote option, Jagannathan Raman, 2020/02/24
- [PATCH v5 29/50] multi-process: add parse_cmdline in remote process, Jagannathan Raman, 2020/02/24
- [PATCH v5 28/50] multi-process: add remote options parser, Jagannathan Raman, 2020/02/24
- [PATCH v5 32/50] multi-process: Use separate MMIO communication channel,
Jagannathan Raman <=
- [PATCH v5 33/50] multi-process: perform device reset in the remote process, Jagannathan Raman, 2020/02/24
- [PATCH v5 34/50] multi-process/mon: choose HMP commands based on target, Jagannathan Raman, 2020/02/24
- [PATCH v5 35/50] multi-process/mon: stub functions to enable QMP module for remote process, Jagannathan Raman, 2020/02/24
- [PATCH v5 30/50] multi-process: send heartbeat messages to remote, Jagannathan Raman, 2020/02/24
- [PATCH v5 31/50] multi-process: handle heartbeat messages in remote process, Jagannathan Raman, 2020/02/24
- [PATCH v5 38/50] multi-process/mon: Initialize QMP module for remote processes, Jagannathan Raman, 2020/02/24
- [PATCH v5 43/50] multi-process/mig: Load VMSD in the proxy object, Jagannathan Raman, 2020/02/24
- [PATCH v5 42/50] multi-process/mig: Send VMSD of remote to the Proxy object, Jagannathan Raman, 2020/02/24
- [PATCH v5 37/50] multi-process/mon: Refactor monitor/chardev functions out of vl.c, Jagannathan Raman, 2020/02/24
- [PATCH v5 36/50] multi-process/mon: enable QMP module support in the remote process, Jagannathan Raman, 2020/02/24