diff options
author | Andrei Vagin <avagin@google.com> | 2019-03-29 16:26:36 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-03-29 16:27:38 -0700 |
commit | a046054ba35e8d8c4882f9311dc964eaa1497d58 (patch) | |
tree | 7cdb13fc8f5f57716b143f94188f0f01169b1c6c /runsc/sandbox/network.go | |
parent | 26e8d9981fcf6d08199a9fd9c609d9715c3cf37e (diff) |
gvisor/runsc: enable generic segmentation offload (GSO)
The linux packet socket can handle GSO packets, so we can segment packets to
64K instead of the MTU which is usually 1500.
Here are numbers for the nginx-1m test:
runsc: 579330.01 [Kbytes/sec] received
runsc-gso: 1794121.66 [Kbytes/sec] received
runc: 2122139.06 [Kbytes/sec] received
and for tcp_benchmark:
$ tcp_benchmark --duration 15 --ideal
[ 4] 0.0-15.0 sec 86647 MBytes 48456 Mbits/sec
$ tcp_benchmark --client --duration 15 --ideal
[ 4] 0.0-15.0 sec 2173 MBytes 1214 Mbits/sec
$ tcp_benchmark --client --duration 15 --ideal --gso 65536
[ 4] 0.0-15.0 sec 19357 MBytes 10825 Mbits/sec
PiperOrigin-RevId: 241072403
Change-Id: I20b03063a1a6649362b43609cbbc9b59be06e6d5
Diffstat (limited to 'runsc/sandbox/network.go')
-rw-r--r-- | runsc/sandbox/network.go | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index ec0a252d1..be924ae25 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -26,6 +26,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/urpc" "gvisor.googlesource.com/gvisor/runsc/boot" @@ -67,7 +68,7 @@ func setupNetwork(conn *urpc.Client, pid int, spec *specs.Spec, conf *boot.Confi // Build the path to the net namespace of the sandbox process. // This is what we will copy. nsPath := filepath.Join("/proc", strconv.Itoa(pid), "ns/net") - if err := createInterfacesAndRoutesFromNS(conn, nsPath); err != nil { + if err := createInterfacesAndRoutesFromNS(conn, nsPath, conf.GSO); err != nil { return fmt.Errorf("creating interfaces from net namespace %q: %v", nsPath, err) } case boot.NetworkHost: @@ -137,7 +138,7 @@ func isRootNS() (bool, error) { // createInterfacesAndRoutesFromNS scrapes the interface and routes from the // net namespace with the given path, creates them in the sandbox, and removes // them from the host. -func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string) error { +func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, enableGSO bool) error { // Join the network namespace that we will be copying. restore, err := joinNetNS(nsPath) if err != nil { @@ -246,6 +247,19 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string) error { return fmt.Errorf("getting link for interface %q: %v", iface.Name, err) } + if enableGSO { + gso, err := isGSOEnabled(fd, iface.Name) + if err != nil { + return fmt.Errorf("getting GSO for interface %q: %v", iface.Name, err) + } + if gso { + if err := syscall.SetsockoptInt(fd, syscall.SOL_PACKET, unix.PACKET_VNET_HDR, 1); err != nil { + return fmt.Errorf("unable to enable the PACKET_VNET_HDR option: %v", err) + } + link.GSOMaxSize = ifaceLink.Attrs().GSOMaxSize + } + } + // Collect the addresses for the interface, enable forwarding, // and remove them from the host. for _, addr := range ip4addrs { |