Skip to content

Conversation

@kingcrimsontianyu
Copy link
Contributor

@kingcrimsontianyu kingcrimsontianyu commented Feb 6, 2026

This PR adds a new utility function drop_file_page_cache() which uses posix_fadvise(POSIX_FADV_DONTNEED) to
evict cached pages for a specific file. Unlike the existing system-wide cache drop, this approach has the following advantages:

  • Requires no elevated privileges
  • Affects only the specified file
  • Allows cache dropping for a specified range (offset, length)
  • Has minimal overhead (no child process spawned)

This is the preferred method for benchmark cache invalidation, which is inspired by fio implementation.

This PR also renames clear_page_cache() to drop_system_page_cache() to align with Linux kernel terminology. The old function is now deprecated.

@copy-pr-bot
Copy link

copy-pr-bot bot commented Feb 6, 2026

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@kingcrimsontianyu kingcrimsontianyu changed the title Add a better page cache dropping function for per file, and unprivileged use Add a better page cache dropping function for per file, unprivileged use Feb 6, 2026
@kingcrimsontianyu kingcrimsontianyu added c++ Affects the C++ API of KvikIO improvement Improves an existing functionality non-breaking Introduces a non-breaking change python Affects the Python API of KvikIO labels Feb 6, 2026
@kingcrimsontianyu kingcrimsontianyu marked this pull request as ready for review February 6, 2026 21:07
@kingcrimsontianyu kingcrimsontianyu requested review from a team as code owners February 6, 2026 21:07

// 6 pages remain in the page cache
auto [cached_pages, _] = kvikio::get_page_cache_info(_filepath.string());
EXPECT_EQ(cached_pages, 6);
Copy link
Contributor Author

@kingcrimsontianyu kingcrimsontianyu Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test file only occupies 10 pages, and on a normally operating CI, I'd expect the file data to be fully resident in the page cache. In an extreme case when the CI system receives complete memory pressure, it is possible, on paper, that some pages of this test file get evicted, where the condition should be EXPECT_LE(cached_pages, 6); but I consider that case extremely unlikely.

I'm open to changing this to LE for absolute correctness though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's see if this causes issues in CI :)

drop_file_page_cache(file.fd(), offset, length, sync_first);
}

bool drop_system_page_cache(bool reclaim_dentries_and_inodes, bool sync_first)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes: drop_system_page_cache 's return value reflects whether the users have the elevated privilege to drop the system wide cache using /proc/sys/vm/drop_caches, whereas drop_file_page_cache has no privilege requirement. Hence the return value asymmetry.

Copy link
Contributor

@vuule vuule left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small suggestion on the error APIs, the actual meat of the PR looks good.

Comment on lines 18 to 20
GenericSystemError::GenericSystemError(const std::string& msg) : GenericSystemError(msg.c_str()) {}

GenericSystemError::GenericSystemError(const char* msg) : GenericSystemError(errno, msg) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid these overloads with std::string_view?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I noticed that the base class std::system_error has the following overloads:

system_error( std::error_code ec, const std::string& what_arg );
system_error( std::error_code ec, const char* what_arg );

Since the base class has no overload with string_view, the subclass, if having a string_view in the constructor, needs to pass it to the base class's std::string overload (performs string construction, defying micro-optimization), or to char const* overload (this looks dangerous since string_view.data() is likely not null terminated).

But I think the existing code GenericSystemError::GenericSystemError(const std::string& msg) : GenericSystemError(msg.c_str()) {} defies the micro-optimization too, as a string is constructed from the char array for the base class. So I've just made some further changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So with how GenericSystemError(std::string const& msg); and GenericSystemError(char const* msg); are defined now, I think copy is completely avoided.


// 6 pages remain in the page cache
auto [cached_pages, _] = kvikio::get_page_cache_info(_filepath.string());
EXPECT_EQ(cached_pages, 6);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's see if this causes issues in CI :)

@kingcrimsontianyu
Copy link
Contributor Author

/merge

@rapids-bot rapids-bot bot merged commit aaea7f6 into rapidsai:main Feb 10, 2026
63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Affects the C++ API of KvikIO improvement Improves an existing functionality non-breaking Introduces a non-breaking change python Affects the Python API of KvikIO

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants