summary refs log tree commit diff
path: root/crosvm_plugin
diff options
context:
space:
mode:
authorMatt Delco <delco@google.com>2019-04-17 15:14:11 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-04-24 15:51:11 -0700
commite3fdadb8e18d567f7e2377613d875f12243b785a (patch)
treea3296ca5dc8e0c3c11dbaecec3957329c92b8f21 /crosvm_plugin
parent2ec62db5f77cd52fe934e87d3be3c832251f4748 (diff)
downloadcrosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.tar
crosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.tar.gz
crosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.tar.bz2
crosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.tar.lz
crosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.tar.xz
crosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.tar.zst
crosvm-e3fdadb8e18d567f7e2377613d875f12243b785a.zip
crosvm: use pipe instead of socket for vcpu communication
Pipes have better performance than sockets, so switch the vcpu
communication over to pipes.  The vm communication channels will
continue to use sockets since that communication isn't performance
critical (and those messages sometimes exchange file descriptors, and
that functionality requires sockets).

TEST=local compile and confirmed that my diagnostic plugin is still
happy. The time it takes to run my benchmark plugin has decreased by
20%.  This combined with my prior commit results in a net wall-clock
time reduction of 32%.
BUG=None

Change-Id: I44c198d62a3bbe3b539ff6ac79707d02488876e3
Signed-off-by: Matt Delco <delco@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1572873
Commit-Ready: Matt Delco <delco@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'crosvm_plugin')
-rw-r--r--crosvm_plugin/src/lib.rs32
1 files changed, 19 insertions, 13 deletions
diff --git a/crosvm_plugin/src/lib.rs b/crosvm_plugin/src/lib.rs
index d1bb665..a6fd4df 100644
--- a/crosvm_plugin/src/lib.rs
+++ b/crosvm_plugin/src/lib.rs
@@ -17,6 +17,7 @@
 
 use std::env;
 use std::fs::File;
+use std::io::{Read, Write};
 use std::mem::{size_of, swap};
 use std::os::raw::{c_int, c_void};
 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
@@ -358,14 +359,17 @@ impl crosvm {
     fn load_all_vcpus(&mut self) -> result::Result<(), c_int> {
         let mut r = MainRequest::new();
         r.mut_get_vcpus();
-        let (_, files) = self.main_transaction(&r, &[])?;
-        if files.is_empty() {
+        let (_, mut files) = self.main_transaction(&r, &[])?;
+        if files.is_empty() || files.len() % 2 != 0 {
             return Err(EPROTO);
         }
-        let vcpus = files
-            .into_iter()
-            .map(|f| crosvm_vcpu::new(fd_cast(f)))
-            .collect();
+
+        let mut vcpus = Vec::with_capacity(files.len() / 2);
+        while files.len() > 1 {
+            let write_pipe = files.remove(0);
+            let read_pipe = files.remove(0);
+            vcpus.push(crosvm_vcpu::new(fd_cast(read_pipe), fd_cast(write_pipe)));
+        }
         // Only called once by the `from_connection` constructor, which makes a new unique
         // `self.vcpus`.
         let self_vcpus = Arc::get_mut(&mut self.vcpus).unwrap();
@@ -919,7 +923,8 @@ pub struct crosvm_vcpu_event {
 }
 
 pub struct crosvm_vcpu {
-    socket: UnixDatagram,
+    read_pipe: File,
+    write_pipe: File,
     send_init: bool,
     request_buffer: Vec<u8>,
     response_buffer: Vec<u8>,
@@ -927,9 +932,10 @@ pub struct crosvm_vcpu {
 }
 
 impl crosvm_vcpu {
-    fn new(socket: UnixDatagram) -> crosvm_vcpu {
+    fn new(read_pipe: File, write_pipe: File) -> crosvm_vcpu {
         crosvm_vcpu {
-            socket,
+            read_pipe,
+            write_pipe,
             send_init: true,
             request_buffer: Vec::new(),
             response_buffer: vec![0; MAX_DATAGRAM_SIZE],
@@ -941,16 +947,16 @@ impl crosvm_vcpu {
         request
             .write_to_vec(&mut self.request_buffer)
             .map_err(proto_error_to_int)?;
-        self.socket
-            .send(self.request_buffer.as_slice())
+        self.write_pipe
+            .write(self.request_buffer.as_slice())
             .map_err(|e| -e.raw_os_error().unwrap_or(EINVAL))?;
         Ok(())
     }
 
     fn vcpu_recv(&mut self) -> result::Result<VcpuResponse, c_int> {
         let msg_size = self
-            .socket
-            .recv(&mut self.response_buffer)
+            .read_pipe
+            .read(&mut self.response_buffer)
             .map_err(|e| -e.raw_os_error().unwrap_or(EINVAL))?;
 
         let response: VcpuResponse =