mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
Prepopulating pages for disk-backed MemoryFiles has proved to be futile.
The mf.MapInternal()+safemem.CopySeq() approach used right now incurs a lot of
page faults without page population. Page-by-page faults incurs a lot of
context switching.
On the other hand, the write syscall makes one context switch to kernel, and
faults all the pages that are touched during write. Note that safemem.CopySeq()
avoids a syscall and hence can be faster sometimes when the underlying page
is populated. But with disk writebacks, it is hard to predict/account what is
populated. Writebacks can happen asynchronously based on system load.
Benchmark results show that FIO write performance improves a lot on rootfs:
```
goos: linux
goarch: amd64
cpu: Intel(R) Xeon(R) CPU @ 2.80GHz
│ benchout.runsc-before │ benchout.runsc-after │
│ sec/op │ sec/op vs base │
BuildABSL/page_cache.clean/filesystem.bindfs-4 90.20 ± 2% 89.44 ± 1% ~ (p=0.382 n=8)
BuildGRPC/page_cache.clean/filesystem.bindfs-4 626.0 ± 1% 626.8 ± 0% ~ (p=0.505 n=8)
RubySpecTest/page_cache.clean/filesystem.bindfs-4 52.11 ± 1% 52.37 ± 1% ~ (p=0.105 n=8)
Fio/operation.write/blockSize.4K/filesystem.rootfs-4 2.509m ± 0% 2.509m ± 0% ~ (p=0.878 n=8)
Fio/operation.write/blockSize.64K/filesystem.rootfs-4 2.009m ± 0% 1.507m ± 0% -24.98% (p=0.000 n=8)
Fio/operation.write/blockSize.1024K/filesystem.rootfs-4 2.008m ± 0% 1.508m ± 0% -24.90% (p=0.000 n=8)
│ benchout.runsc-before │ benchout.runsc-after │
│ bandwidth.bytes_per_second │ bandwidth.bytes_per_second vs base │
Fio/operation.write/blockSize.4K/filesystem.rootfs-4 649.1M ± 2% 705.2M ± 2% +8.64% (p=0.000 n=8)
Fio/operation.write/blockSize.64K/filesystem.rootfs-4 991.1M ± 1% 1499.1M ± 3% +51.25% (p=0.000 n=8)
Fio/operation.write/blockSize.1024K/filesystem.rootfs-4 1.198G ± 2% 1.945G ± 2% +62.34% (p=0.000 n=8)
│ benchout.runsc-before │ benchout.runsc-after │
│ io_ops.ops_per_second │ io_ops.ops_per_second vs base │
Fio/operation.write/blockSize.4K/filesystem.rootfs-4 158.5k ± 2% 172.2k ± 2% +8.64% (p=0.000 n=8)
Fio/operation.write/blockSize.64K/filesystem.rootfs-4 15.12k ± 1% 22.87k ± 3% +51.25% (p=0.000 n=8)
Fio/operation.write/blockSize.1024K/filesystem.rootfs-4 1.143k ± 2% 1.855k ± 2% +62.34% (p=0.000 n=8)
│ benchout.runsc-before │ benchout.runsc-after │
│ load.sec │ load.sec vs base │
RubySpecTest/page_cache.clean/filesystem.bindfs-4 7.555 ± 1% 7.585 ± 1% ~ (p=0.457 n=8)
```
PiperOrigin-RevId: 548021076
163 lines
3.6 KiB
Python
163 lines
3.6 KiB
Python
load("//tools:defs.bzl", "go_library", "go_test")
|
|
load("//tools/go_generics:defs.bzl", "go_template_instance")
|
|
load("//pkg/sync/locking:locking.bzl", "declare_mutex", "declare_rwmutex")
|
|
|
|
package(default_applicable_licenses = ["//:license"])
|
|
|
|
licenses(["notice"])
|
|
|
|
go_template_instance(
|
|
name = "dentry_list",
|
|
out = "dentry_list.go",
|
|
package = "tmpfs",
|
|
prefix = "dentry",
|
|
template = "//pkg/ilist:generic_list",
|
|
types = {
|
|
"Element": "*dentry",
|
|
"Linker": "*dentry",
|
|
},
|
|
)
|
|
|
|
go_template_instance(
|
|
name = "fstree",
|
|
out = "fstree.go",
|
|
package = "tmpfs",
|
|
prefix = "generic",
|
|
template = "//pkg/sentry/vfs/genericfstree:generic_fstree",
|
|
types = {
|
|
"Dentry": "dentry",
|
|
},
|
|
)
|
|
|
|
go_template_instance(
|
|
name = "inode_refs",
|
|
out = "inode_refs.go",
|
|
package = "tmpfs",
|
|
prefix = "inode",
|
|
template = "//pkg/refs:refs_template",
|
|
types = {
|
|
"T": "inode",
|
|
},
|
|
)
|
|
|
|
declare_mutex(
|
|
name = "inode_mutex",
|
|
out = "inode_mutex.go",
|
|
package = "tmpfs",
|
|
prefix = "inode",
|
|
)
|
|
|
|
declare_mutex(
|
|
name = "pages_used_mutex",
|
|
out = "pages_used_mutex.go",
|
|
package = "tmpfs",
|
|
prefix = "pagesUsed",
|
|
)
|
|
|
|
declare_mutex(
|
|
name = "iter_mutex",
|
|
out = "iter_mutex.go",
|
|
package = "tmpfs",
|
|
prefix = "iter",
|
|
)
|
|
|
|
declare_rwmutex(
|
|
name = "filesystem_mutex",
|
|
out = "filesystem_mutex.go",
|
|
package = "tmpfs",
|
|
prefix = "filesystem",
|
|
)
|
|
|
|
go_library(
|
|
name = "tmpfs",
|
|
srcs = [
|
|
"dentry_list.go",
|
|
"device_file.go",
|
|
"directory.go",
|
|
"filesystem.go",
|
|
"filesystem_mutex.go",
|
|
"fstree.go",
|
|
"inode_mutex.go",
|
|
"inode_refs.go",
|
|
"iter_mutex.go",
|
|
"named_pipe.go",
|
|
"pages_used_mutex.go",
|
|
"regular_file.go",
|
|
"save_restore.go",
|
|
"socket_file.go",
|
|
"symlink.go",
|
|
"tmpfs.go",
|
|
],
|
|
visibility = ["//pkg/sentry:internal"],
|
|
deps = [
|
|
"//pkg/abi/linux",
|
|
"//pkg/atomicbitops",
|
|
"//pkg/context",
|
|
"//pkg/errors/linuxerr",
|
|
"//pkg/fd",
|
|
"//pkg/fspath",
|
|
"//pkg/hostarch",
|
|
"//pkg/log",
|
|
"//pkg/refs",
|
|
"//pkg/safemem",
|
|
"//pkg/sentry/arch",
|
|
"//pkg/sentry/fsimpl/lock",
|
|
"//pkg/sentry/fsmetric",
|
|
"//pkg/sentry/fsutil",
|
|
"//pkg/sentry/hostfd",
|
|
"//pkg/sentry/kernel/auth",
|
|
"//pkg/sentry/kernel/pipe",
|
|
"//pkg/sentry/kernel/time",
|
|
"//pkg/sentry/memmap",
|
|
"//pkg/sentry/pgalloc",
|
|
"//pkg/sentry/platform",
|
|
"//pkg/sentry/socket/unix/transport",
|
|
"//pkg/sentry/uniqueid",
|
|
"//pkg/sentry/usage",
|
|
"//pkg/sentry/vfs",
|
|
"//pkg/sentry/vfs/memxattr",
|
|
"//pkg/sync",
|
|
"//pkg/sync/locking",
|
|
"//pkg/usermem",
|
|
],
|
|
)
|
|
|
|
go_test(
|
|
name = "benchmark_test",
|
|
size = "small",
|
|
srcs = ["benchmark_test.go"],
|
|
deps = [
|
|
":tmpfs",
|
|
"//pkg/abi/linux",
|
|
"//pkg/fspath",
|
|
"//pkg/refs",
|
|
"//pkg/sentry/contexttest",
|
|
"//pkg/sentry/kernel/auth",
|
|
"//pkg/sentry/vfs",
|
|
],
|
|
)
|
|
|
|
go_test(
|
|
name = "tmpfs_test",
|
|
size = "small",
|
|
srcs = [
|
|
"pipe_test.go",
|
|
"regular_file_test.go",
|
|
"stat_test.go",
|
|
"tmpfs_test.go",
|
|
],
|
|
library = ":tmpfs",
|
|
deps = [
|
|
"//pkg/abi/linux",
|
|
"//pkg/atomicbitops",
|
|
"//pkg/context",
|
|
"//pkg/errors/linuxerr",
|
|
"//pkg/fspath",
|
|
"//pkg/sentry/contexttest",
|
|
"//pkg/sentry/fsimpl/lock",
|
|
"//pkg/sentry/kernel/auth",
|
|
"//pkg/sentry/vfs",
|
|
"//pkg/usermem",
|
|
],
|
|
)
|