Skip to content

Commit

Permalink
Make busy rx/tx loop faster.
Browse files Browse the repository at this point in the history
This commit improves the performance of the rx and tx loop by 1) moving
allocations to outside the loop and by 2) eliminating an unnecessary
Write call.

As long as gvproxy implements the same improvements, this should result
in ~20% more reqs/sec.

For posterity, here's the upstream PR for the gvproxy side of things:
containers/gvisor-tap-vsock#215
  • Loading branch information
Philipp Winter committed May 8, 2023
1 parent 6ba0e9e commit 0469822
Showing 1 changed file with 8 additions and 16 deletions.
24 changes: 8 additions & 16 deletions proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"time"

"github.com/containers/gvisor-tap-vsock/pkg/transport"
"github.com/songgao/packets/ethernet"
"github.com/songgao/water"
"github.com/vishvananda/netlink"
"gvisor.dev/gvisor/pkg/tcpip/header"
Expand Down Expand Up @@ -122,39 +121,32 @@ func linkUp() error {
return netlink.LinkSetUp(link)
}

func rx(conn net.Conn, tap *water.Interface, errCh chan error, mtu int) {
func rx(conn io.ReadWriteCloser, tap io.ReadWriteCloser, errCh chan error, mtu int) {
elog.Println("Waiting for frames from enclave application.")
var frame ethernet.Frame
frame := make([]byte, mtu)
size := make([]byte, 2)
for {
frame.Resize(mtu)
n, err := tap.Read([]byte(frame))
if err != nil {
errCh <- fmt.Errorf("failed to read packet from TAP device: %w", err)
return
}
frame = frame[:n]

size := make([]byte, 2)
binary.LittleEndian.PutUint16(size, uint16(n))

if _, err := conn.Write(size); err != nil {
errCh <- fmt.Errorf("failed to write frame size to connection: %w", err)
return
}
if _, err := conn.Write(frame); err != nil {
if _, err := conn.Write(append(size, frame[:n]...)); err != nil {
errCh <- fmt.Errorf("failed to write frame to connection: %w", err)
return
}
}
}

func tx(conn net.Conn, tap *water.Interface, errCh chan error, mtu int) {
func tx(conn net.Conn, tap io.ReadWriteCloser, errCh chan error, mtu int) {
elog.Println("Waiting for frames from host.")
sizeBuf := make([]byte, 2)
size := make([]byte, 2)
buf := make([]byte, mtu+header.EthernetMinimumSize)

for {
n, err := io.ReadFull(conn, sizeBuf)
n, err := io.ReadFull(conn, size)
if err != nil {
errCh <- fmt.Errorf("failed to read frame size from connection: %w", err)
return
Expand All @@ -163,7 +155,7 @@ func tx(conn net.Conn, tap *water.Interface, errCh chan error, mtu int) {
errCh <- fmt.Errorf("received unexpected frame size %d", n)
return
}
size := int(binary.LittleEndian.Uint16(sizeBuf[0:2]))
size := int(binary.LittleEndian.Uint16(size[0:2]))

n, err = io.ReadFull(conn, buf[:size])
if err != nil {
Expand Down

0 comments on commit 0469822

Please sign in to comment.