Hi Ms.Khan I have added a new api *test_cachestat_mmap *to validate cachestat behavior with memory-mapped files. attached the output file here.
Thanks, Suresh K C On Fri, May 16, 2025 at 6:12 PM Suresh K C <[email protected]> wrote: > From: Suresh K C <[email protected]> > > This patch adds a new test case to validate cachestat behavior with > memory-mapped files using mmap(). The test ensures that pages are > properly cached when accessed via mmap and verifies the expected > number of cached pages. > > Additionally, a test case for /proc/cpuinfo has been added to observe > how cachestat handles virtual files under /proc. This helps improve > coverage of edge cases involving pseudo-filesystems > > Signed-off-by: Suresh K C <[email protected]> > --- > .../selftests/cachestat/test_cachestat.c | 69 ++++++++++++++++++- > 1 file changed, 67 insertions(+), 2 deletions(-) > > diff --git a/tools/testing/selftests/cachestat/test_cachestat.c > b/tools/testing/selftests/cachestat/test_cachestat.c > index 632ab44737ec..81e7f6dd2279 100644 > --- a/tools/testing/selftests/cachestat/test_cachestat.c > +++ b/tools/testing/selftests/cachestat/test_cachestat.c > @@ -22,7 +22,7 @@ > > static const char * const dev_files[] = { > "/dev/zero", "/dev/null", "/dev/urandom", > - "/proc/version", "/proc" > + "/proc/version","/proc/cpuinfo","/proc" > }; > > void print_cachestat(struct cachestat *cs) > @@ -202,6 +202,65 @@ static int test_cachestat(const char *filename, bool > write_random, bool create, > return ret; > } > > +bool test_cachestat_mmap(void){ > + > + size_t PS = sysconf(_SC_PAGESIZE); > + size_t filesize = PS * 512 * 2;; > + int syscall_ret; > + size_t compute_len = PS * 512; > + struct cachestat_range cs_range = { PS, compute_len }; > + char *filename = "tmpshmcstat"; > + unsigned long num_pages = compute_len / PS; > + struct cachestat cs; > + bool ret = true; > + int fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666); > + if (fd < 0) { > + ksft_print_msg("Unable to create mmap file.\n"); > + ret = false; > + goto out; > + } > + if (ftruncate(fd, filesize)) { > + ksft_print_msg("Unable to truncate mmap file.\n"); > + ret = false; > + goto close_fd; > + } > + if (!write_exactly(fd, filesize)) { > + ksft_print_msg("Unable to write to mmap file.\n"); > + ret = false; > + goto close_fd; > + } > + char *map = mmap(NULL, filesize, PROT_READ | PROT_WRITE, > MAP_SHARED, fd, 0); > + if (map == MAP_FAILED) { > + ksft_print_msg("mmap failed.\n"); > + ret = false; > + goto close_fd; > + } > + > + for (int i = 0; i < filesize; i++) { > + map[i] = 'A'; > + } > + map[filesize - 1] = 'X'; > + > + syscall_ret = syscall(__NR_cachestat, fd, &cs_range, &cs, 0); > + > + if (syscall_ret) { > + ksft_print_msg("Cachestat returned non-zero.\n"); > + ret = false; > + } else { > + print_cachestat(&cs); > + if (cs.nr_cache + cs.nr_evicted != num_pages) { > + ksft_print_msg("Total number of cached and evicted > pages is off.\n"); > + ret = false; > + } > + } > + > +close_fd: > + close(fd); > + unlink(filename); > +out: > + return ret; > +} > + > bool test_cachestat_shmem(void) > { > size_t PS = sysconf(_SC_PAGESIZE); > @@ -274,7 +333,7 @@ int main(void) > ret = 1; > } > > - for (int i = 0; i < 5; i++) { > + for (int i = 0; i < 6; i++) { > const char *dev_filename = dev_files[i]; > > if (test_cachestat(dev_filename, false, false, false, > @@ -315,5 +374,11 @@ int main(void) > ret = 1; > } > > + if (test_cachestat_mmap()) > + ksft_test_result_pass("cachestat works with a mmap > file\n"); > + else { > + ksft_test_result_fail("cachestat fails with a mmap > file\n"); > + ret = 1; > + } > return ret; > } > -- > 2.43.0 > >
TAP version 13 1..9 ok 1 bad file descriptor recognized # Create/open /dev/zero # Cachestat call returned 0 # Using cachestat: Cached: 0, Dirty: 0, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 2 cachestat works with /dev/zero # Create/open /dev/null # Cachestat call returned 0 # Using cachestat: Cached: 0, Dirty: 0, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 3 cachestat works with /dev/null # Create/open /dev/urandom # Cachestat call returned 0 # Using cachestat: Cached: 0, Dirty: 0, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 4 cachestat works with /dev/urandom # Create/open /proc/version # Cachestat call returned -1 # Cachestat returned non-zero. not ok 5 cachestat fails with /proc/version # Create/open /proc/cpuinfo # Cachestat call returned -1 # Cachestat returned non-zero. not ok 6 cachestat fails with /proc/cpuinfo # Create/open /proc # Cachestat call returned -1 # Cachestat returned non-zero. not ok 7 cachestat fails with /proc # Create/open tmpfilecachestat # Cachestat call returned 0 # Using cachestat: Cached: 4, Dirty: 4, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 8 cachestat works with a normal file # Create/open tmpfilecachestat # Cachestat call returned 0 # Using cachestat: Cached: 4, Dirty: 4, Writeback: 0, Evicted: 0, Recently Evicted: 0 # Cachestat call (after fsync) returned 0 # Using cachestat: Cached: 4, Dirty: 0, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 9 cachestat fsync works with a normal file # Using cachestat: Cached: 512, Dirty: 0, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 10 cachestat works with a shmem file # Using cachestat: Cached: 512, Dirty: 512, Writeback: 0, Evicted: 0, Recently Evicted: 0 ok 11 cachestat works with a mmap file
