cachestat(2)
Query page cache status (resident, dirty, writeback, evicted) for a byte range of an open file.
- Since
- Linux 6.5check your kernel →
- glibc
- none (use syscall(2)); glibc 2.41+ may provide a wrapper
- System
- Linux
- Man page
- cachestat(2)
Synopsis
#include <linux/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
long syscall(SYS_cachestat, int fd,
struct cachestat_range *cstat_range,
struct cachestat *cstat,
unsigned int flags);Rod's take
cachestat(2) replaces the mmap-first mincore(2) dance for resident-page checks and adds what mincore never had: dirty count, writeback count, and eviction statistics. Pass len=0 for the whole file. flags must be 0. No glibc wrapper on most systems; use syscall(SYS_cachestat, ...). Hugepage-backed files and DAX mappings report zeros. Added in Linux 6.5; check uname -r before deploying.
Flags and arguments that matter
| Name | What it does |
|---|---|
| struct cachestat_range | off: start byte; len: length in bytes (0 = to EOF). |
| nr_cache | Pages currently resident in the page cache. |
| nr_dirty | Pages modified in cache but not yet written to storage. |
| nr_writeback | Pages currently being written back to storage. |
| nr_evicted | Pages evicted from cache since the last cachestat call on this fd. |
| nr_recently_evicted | Pages evicted under memory pressure (PG_workingset) since the last call. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| EFAULT | cstat_range or cstat is not a valid user address. |
| EINVAL | flags is non-zero. |
| EBADF | fd is not a valid open file descriptor. |
Example
#include <linux/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
struct cachestat_range range = { .off = 0, .len = 0 };
struct cachestat cs = {0};
if (syscall(SYS_cachestat, fd, &range, &cs, 0) < 0)
err(1, "cachestat");
printf("resident: %llu pages\ndirty: %llu pages\n",
cs.nr_cache, cs.nr_dirty);Trimmed from the full walkthrough in cachestat(2): querying the page cache without mmap.
BSD equivalent
FreeBSD: no equivalent. mincore(3) is available with the same mmap-first requirement as Linux mincore(2).
The long version, from the console
Sources
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
