Files
seaweedfs/weed/util/fadvise_linux_test.go
T
Chris LuandGitHub e1fa4ec756 perf(cache): drop OS page cache after disk cache reads (#9098)
* perf(cache): drop OS page cache after disk cache reads

After reading from the on-disk chunk cache, advise the kernel via
FADV_DONTNEED to release the corresponding page cache pages. This
prevents double-caching the same data in both user-space and kernel
page caches, freeing RAM for other uses on systems with large disk
caches.

* fix(cache): guard dropReadCache against zero length and invalid fd

A zero-length fadvise is interpreted as "to end of file" on Linux,
which would inadvertently drop the page cache for the entire remainder
of the cache volume. Also check fd >= 0 to avoid unnecessary syscalls
when the backend file is closed.

* perf(cache): only apply FADV_DONTNEED for reads >= 1 MiB

For small needle reads the syscall overhead outweighs the memory
savings, and the kernel page cache is more beneficial for warm data.
Restrict fadvise to reads of at least 1 MiB where the freed page
cache is meaningful.
2026-04-16 09:38:42 -07:00

38 lines
796 B
Go

//go:build linux
package util
import (
"os"
"testing"
)
func TestDropOSPageCache(t *testing.T) {
f, err := os.CreateTemp("", "fadvise_test")
if err != nil {
t.Fatalf("failed to create temp file: %v", err)
}
defer os.Remove(f.Name())
defer f.Close()
data := make([]byte, 4096)
for i := range data {
data[i] = byte(i % 256)
}
if _, err := f.Write(data); err != nil {
t.Fatalf("failed to write test data: %v", err)
}
// Read the data back to populate page cache
buf := make([]byte, 4096)
if _, err := f.ReadAt(buf, 0); err != nil {
t.Fatalf("failed to read test data: %v", err)
}
// Call DropOSPageCache and verify no error
fd := int(f.Fd())
if err := DropOSPageCache(fd, 0, int64(len(data))); err != nil {
t.Errorf("DropOSPageCache returned error: %v", err)
}
}