$RodHat_
Syscall reference · Filesystem

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

NameWhat it does
struct cachestat_rangeoff: start byte; len: length in bytes (0 = to EOF).
nr_cachePages currently resident in the page cache.
nr_dirtyPages modified in cache but not yet written to storage.
nr_writebackPages currently being written back to storage.
nr_evictedPages evicted from cache since the last cachestat call on this fd.
nr_recently_evictedPages evicted under memory pressure (PG_workingset) since the last call.

Errors you will actually hit

errnoMeaning
EFAULTcstat_range or cstat is not a valid user address.
EINVALflags is non-zero.
EBADFfd 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

  1. cachestat(2), man7.org
  2. cachestat: query the page cache, LWN.net

Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.