diff options
author | Zach Koopmans <zkoopmans@google.com> | 2021-03-10 14:34:47 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-03-10 14:36:41 -0800 |
commit | a44dc15bdce80adf4468972347e3bd7f3ed8d573 (patch) | |
tree | 769abc0da57a3b789c81c68baa1e286d8708de33 /test/benchmarks/fs | |
parent | 14fc2ddd6cb2f25482ef0d16ec5e3ffda3dd0f6e (diff) |
Add a rootfs filesystem to fs benchmarks. Also, fix fio benchmark.
The previous "bind" filesystem, already included in go/runsc-benchmarks
is a remote re-validate mount. However, the non-re-validate mount
was not present, and it has been added in the form of rootfs.
Also, fix the fio runs to reads/writes of 10GB as running
with --test.benchtime=Xs may scale beyond the memory available
to tmpfs mounts on buildkite VMs. Currently, our buildkite
pipelines are run on e2-standard-8 machines with 32GB of memory,
allowing tmpfs mounts to safely be at least 10GB.
PiperOrigin-RevId: 362143620
Diffstat (limited to 'test/benchmarks/fs')
-rw-r--r-- | test/benchmarks/fs/BUILD | 1 | ||||
-rw-r--r-- | test/benchmarks/fs/bazel_test.go | 61 | ||||
-rw-r--r-- | test/benchmarks/fs/fio_test.go | 59 |
3 files changed, 46 insertions, 75 deletions
diff --git a/test/benchmarks/fs/BUILD b/test/benchmarks/fs/BUILD index b4f967441..c94caab60 100644 --- a/test/benchmarks/fs/BUILD +++ b/test/benchmarks/fs/BUILD @@ -11,6 +11,7 @@ benchmark_test( "//pkg/test/dockerutil", "//test/benchmarks/harness", "//test/benchmarks/tools", + "@com_github_docker_docker//api/types/mount:go_default_library", ], ) diff --git a/test/benchmarks/fs/bazel_test.go b/test/benchmarks/fs/bazel_test.go index 8baeff0db..7ced963f6 100644 --- a/test/benchmarks/fs/bazel_test.go +++ b/test/benchmarks/fs/bazel_test.go @@ -25,6 +25,13 @@ import ( "gvisor.dev/gvisor/test/benchmarks/tools" ) +// Dimensions here are clean/dirty cache (do or don't drop caches) +// and if the mount on which we are compiling is a tmpfs/bind mount. +type benchmark struct { + clearCache bool // clearCache drops caches before running. + fstype string // type of filesystem to use. +} + // Note: CleanCache versions of this test require running with root permissions. func BenchmarkBuildABSL(b *testing.B) { runBuildBenchmark(b, "benchmarks/absl", "/abseil-cpp", "absl/base/...") @@ -45,17 +52,18 @@ func runBuildBenchmark(b *testing.B, image, workdir, target string) { } defer machine.CleanUp() - // Dimensions here are clean/dirty cache (do or don't drop caches) - // and if the mount on which we are compiling is a tmpfs/bind mount. - benchmarks := []struct { - clearCache bool // clearCache drops caches before running. - tmpfs bool // tmpfs will run compilation on a tmpfs. - }{ - {clearCache: true, tmpfs: false}, - {clearCache: false, tmpfs: false}, - {clearCache: true, tmpfs: true}, - {clearCache: false, tmpfs: true}, + benchmarks := make([]benchmark, 0, 6) + for _, filesys := range []string{harness.BindFS, harness.TmpFS, harness.RootFS} { + benchmarks = append(benchmarks, benchmark{ + clearCache: true, + fstype: filesys, + }) + benchmarks = append(benchmarks, benchmark{ + clearCache: false, + fstype: filesys, + }) } + for _, bm := range benchmarks { pageCache := tools.Parameter{ Name: "page_cache", @@ -67,10 +75,7 @@ func runBuildBenchmark(b *testing.B, image, workdir, target string) { filesystem := tools.Parameter{ Name: "filesystem", - Value: "bind", - } - if bm.tmpfs { - filesystem.Value = "tmpfs" + Value: bm.fstype, } name, err := tools.ParametersToName(pageCache, filesystem) if err != nil { @@ -83,21 +88,25 @@ func runBuildBenchmark(b *testing.B, image, workdir, target string) { container := machine.GetContainer(ctx, b) defer container.CleanUp(ctx) + mts, prefix, cleanup, err := harness.MakeMount(machine, bm.fstype) + if err != nil { + b.Fatalf("Failed to make mount: %v", err) + } + defer cleanup() + + runOpts := dockerutil.RunOpts{ + Image: image, + Mounts: mts, + } + // Start a container and sleep. - if err := container.Spawn(ctx, dockerutil.RunOpts{ - Image: image, - }, "sleep", fmt.Sprintf("%d", 1000000)); err != nil { + if err := container.Spawn(ctx, runOpts, "sleep", fmt.Sprintf("%d", 1000000)); err != nil { b.Fatalf("run failed with: %v", err) } - // If we are running on a tmpfs, copy to /tmp which is a tmpfs. - prefix := "" - if bm.tmpfs { - if out, err := container.Exec(ctx, dockerutil.ExecOpts{}, - "cp", "-r", workdir, "/tmp/."); err != nil { - b.Fatalf("failed to copy directory: %v (%s)", err, out) - } - prefix = "/tmp" + if out, err := container.Exec(ctx, dockerutil.ExecOpts{}, + "cp", "-rf", workdir, prefix+"/."); err != nil { + b.Fatalf("failed to copy directory: %v (%s)", err, out) } b.ResetTimer() @@ -118,7 +127,7 @@ func runBuildBenchmark(b *testing.B, image, workdir, target string) { WorkDir: prefix + workdir, }, "bazel", "build", "-c", "opt", target) if err != nil { - b.Fatalf("build failed with: %v", err) + b.Fatalf("build failed with: %v logs: %s", err, got) } b.StopTimer() diff --git a/test/benchmarks/fs/fio_test.go b/test/benchmarks/fs/fio_test.go index cc2d1cbbc..f783a2b33 100644 --- a/test/benchmarks/fs/fio_test.go +++ b/test/benchmarks/fs/fio_test.go @@ -21,7 +21,6 @@ import ( "strings" "testing" - "github.com/docker/docker/api/types/mount" "gvisor.dev/gvisor/pkg/test/dockerutil" "gvisor.dev/gvisor/test/benchmarks/harness" "gvisor.dev/gvisor/test/benchmarks/tools" @@ -70,7 +69,7 @@ func BenchmarkFio(b *testing.B) { } defer machine.CleanUp() - for _, fsType := range []mount.Type{mount.TypeBind, mount.TypeTmpfs} { + for _, fsType := range []string{harness.BindFS, harness.TmpFS, harness.RootFS} { for _, tc := range testCases { operation := tools.Parameter{ Name: "operation", @@ -82,7 +81,7 @@ func BenchmarkFio(b *testing.B) { } filesystem := tools.Parameter{ Name: "filesystem", - Value: string(fsType), + Value: fsType, } name, err := tools.ParametersToName(operation, blockSize, filesystem) if err != nil { @@ -95,13 +94,7 @@ func BenchmarkFio(b *testing.B) { container := machine.GetContainer(ctx, b) defer container.CleanUp(ctx) - // Directory and filename inside container where fio will read/write. - outdir := "/data" - outfile := filepath.Join(outdir, "test.txt") - - // Make the required mount and grab a cleanup for bind mounts - // as they are backed by a temp directory (mktemp). - mnt, mountCleanup, err := makeMount(machine, fsType, outdir) + mnts, outdir, mountCleanup, err := harness.MakeMount(machine, fsType) if err != nil { b.Fatalf("failed to make mount: %v", err) } @@ -109,12 +102,9 @@ func BenchmarkFio(b *testing.B) { // Start the container with the mount. if err := container.Spawn( - ctx, - dockerutil.RunOpts{ - Image: "benchmarks/fio", - Mounts: []mount.Mount{ - mnt, - }, + ctx, dockerutil.RunOpts{ + Image: "benchmarks/fio", + Mounts: mnts, }, // Sleep on the order of b.N. "sleep", fmt.Sprintf("%d", 1000*b.N), @@ -122,6 +112,9 @@ func BenchmarkFio(b *testing.B) { b.Fatalf("failed to start fio container with: %v", err) } + // Directory and filename inside container where fio will read/write. + outfile := filepath.Join(outdir, "test.txt") + // For reads, we need a file to read so make one inside the container. if strings.Contains(tc.Test, "read") { fallocateCmd := fmt.Sprintf("fallocate -l %dK %s", tc.Size, outfile) @@ -135,6 +128,7 @@ func BenchmarkFio(b *testing.B) { if err := harness.DropCaches(machine); err != nil { b.Skipf("failed to drop caches with %v. You probably need root.", err) } + cmd := tc.MakeCmd(outfile) if err := harness.DropCaches(machine); err != nil { @@ -154,39 +148,6 @@ func BenchmarkFio(b *testing.B) { } } -// makeMount makes a mount and cleanup based on the requested type. Bind -// and volume mounts are backed by a temp directory made with mktemp. -// tmpfs mounts require no such backing and are just made. -// It is up to the caller to call the returned cleanup. -func makeMount(machine harness.Machine, mountType mount.Type, target string) (mount.Mount, func(), error) { - switch mountType { - case mount.TypeVolume, mount.TypeBind: - dir, err := machine.RunCommand("mktemp", "-d") - if err != nil { - return mount.Mount{}, func() {}, fmt.Errorf("failed to create tempdir: %v", err) - } - dir = strings.TrimSuffix(dir, "\n") - - out, err := machine.RunCommand("chmod", "777", dir) - if err != nil { - machine.RunCommand("rm", "-rf", dir) - return mount.Mount{}, func() {}, fmt.Errorf("failed modify directory: %v %s", err, out) - } - return mount.Mount{ - Target: target, - Source: dir, - Type: mount.TypeBind, - }, func() { machine.RunCommand("rm", "-rf", dir) }, nil - case mount.TypeTmpfs: - return mount.Mount{ - Target: target, - Type: mount.TypeTmpfs, - }, func() {}, nil - default: - return mount.Mount{}, func() {}, fmt.Errorf("illegal mount time not supported: %v", mountType) - } -} - // TestMain is the main method for package fs. func TestMain(m *testing.M) { harness.Init() |