summary refs log tree commit diff
path: root/devices/src/virtio
diff options
context:
space:
mode:
authorStephen Barber <smbarber@chromium.org>2019-10-25 13:14:09 +0200
committerCommit Bot <commit-bot@chromium.org>2019-11-05 19:49:41 +0000
commit1104a730a764633e6590488b31fa801f99512c3c (patch)
tree748638044483e067f199327eb0d31c470e33625d /devices/src/virtio
parent6cb2a930b54fd091e0e13d1e12389cc8165f5a00 (diff)
downloadcrosvm-1104a730a764633e6590488b31fa801f99512c3c.tar
crosvm-1104a730a764633e6590488b31fa801f99512c3c.tar.gz
crosvm-1104a730a764633e6590488b31fa801f99512c3c.tar.bz2
crosvm-1104a730a764633e6590488b31fa801f99512c3c.tar.lz
crosvm-1104a730a764633e6590488b31fa801f99512c3c.tar.xz
crosvm-1104a730a764633e6590488b31fa801f99512c3c.tar.zst
crosvm-1104a730a764633e6590488b31fa801f99512c3c.zip
devices: net: use FileReadWriteVolatile trait for tx
This removes the unnecessary copy on the tx path. On nami, this increases
tx throughput by ~60%.

BUG=chromium:753630
TEST=crostini.NetworkPerf

Cq-Depend: chromium:1873142
Change-Id: I58be5a7acef5d118d34b3c42ffb5a34e90070bf4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1881419
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Stephen Barber <smbarber@chromium.org>
Commit-Queue: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Diffstat (limited to 'devices/src/virtio')
-rw-r--r--devices/src/virtio/net.rs39
1 files changed, 13 insertions, 26 deletions
diff --git a/devices/src/virtio/net.rs b/devices/src/virtio/net.rs
index 740a1d8..20d69da 100644
--- a/devices/src/virtio/net.rs
+++ b/devices/src/virtio/net.rs
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 use std::fmt::{self, Display};
-use std::io::{self, Read, Write};
+use std::io::{self, Write};
 use std::mem;
 use std::net::Ipv4Addr;
 use std::os::unix::io::{AsRawFd, RawFd};
@@ -178,37 +178,24 @@ where
     }
 
     fn process_tx(&mut self) {
-        let mut frame = [0u8; MAX_BUFFER_SIZE];
-
-        // Reads up to `buf.len()` bytes or until there is no more data in `r`, whichever
-        // is smaller.
-        fn read_to_end(mut r: Reader, buf: &mut [u8]) -> io::Result<usize> {
-            let mut count = 0;
-            while count < buf.len() {
-                match r.read(&mut buf[count..]) {
-                    Ok(0) => break,
-                    Ok(n) => count += n,
-                    Err(e) => return Err(e),
-                }
-            }
-
-            Ok(count)
-        }
-
         while let Some(desc_chain) = self.tx_queue.pop(&self.mem) {
             let index = desc_chain.index;
 
             match Reader::new(&self.mem, desc_chain) {
-                Ok(reader) => {
-                    match read_to_end(reader, &mut frame[..]) {
-                        Ok(len) => {
-                            // We need to copy frame into continuous buffer before writing it to tap
-                            // because tap requires frame to complete in a single write.
-                            if let Err(err) = self.tap.write_all(&frame[..len]) {
-                                error!("net: tx: failed to write to tap: {}", err);
+                Ok(mut reader) => {
+                    let expected_count = reader.available_bytes();
+                    match reader.read_to(&mut self.tap, expected_count) {
+                        Ok(count) => {
+                            // Tap writes must be done in one call. If the entire frame was not
+                            // written, it's an error.
+                            if count != expected_count {
+                                error!(
+                                    "net: tx: wrote only {} bytes of {} byte frame",
+                                    count, expected_count
+                                );
                             }
                         }
-                        Err(e) => error!("net: tx: failed to read frame into buffer: {}", e),
+                        Err(e) => error!("net: tx: failed to write frame to tap: {}", e),
                     }
                 }
                 Err(e) => error!("net: failed to create Reader: {}", e),