-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check for buggy preadv2 #3821
Check for buggy preadv2 #3821
Conversation
tokio/src/fs/file.rs
Outdated
let release = unsafe { CStr::from_ptr((*uts.as_ptr()).release.as_ptr()) }; | ||
let release = release.to_bytes(); | ||
release[..4] == b"5.9."[..] || release[..5] == b"5.10."[..] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You beat me to it :)
FWIW in the impl I was brewing I made this comparison with [i8]
avoiding the conversion via CStr
like this:
const _5_9: [i8; 4] = [53, 46, 57, 46]; // [i8] repr of b"5.9."
const _5_10: [i8; 5] = [53, 46, 49, 48, 46]; // [i8] repr of b"5.10."
uts.release[..4] == _5_9 || uts.release[..5] == _5_10
Not that it matters, this function will only be called ~once per process.
I'll run my tests with this impl. |
I've run my test on 5.10 and it succeeds with this PR, and fails on master. |
@wmanley I don't really understand the Linux kernel version numbers here. The Linux git repository only has tags for |
Here's the git repo with the stable kernel versions: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git . This is where the point releases are tagged. I've tested both the mainline and the stable kernel tags. |
I got the impression that you just did a bisection? Which tags did you try? |
I did both. I did a bisection on mainline to identify the specific commits where it was introduced and fixed. Having discovered that it was fixed on mainline I separately and additionally ran the test on the latest stable releases to see if the fix had been cherry-picked to any stable branch. The results of the stable branch checking is as follows:
My conclusion is that the kernel developers aren't/weren't even aware that the bug existed, so the fix for it hasn't been backported. Bisecting to find first bad commit: #3803 (comment) |
Before merging this, I think that we need to have a plan to include testing different kernel versions as part of CI. we don't want to accidentally introduce regressions if we change this code. Granted, testing different kernel versions is not trivial. |
I have not had the time to check in detail. But this project seems like an alternative https://github.com/linuxkit/linuxkit |
I'd be happy to have a crack at this, adapting the kernel testing I'd done in #3803 to CI. So we'd have a few pre-built kernels and run qemu in CI to see if the bug is present or not on each. Ideally we'd have a way of running against the latest RC kernel too to catch future regressions before they happen. But first I'd like to know - is it worthwhile? Does anyone have a real-world benchmark that this helps with, or is there some other reason to want this? |
A benchmark? It's mostly to make sure we catch regressions if we break something on some kernel versions only. |
Not a benchmark for testing, but for #3518. The value in the kernel testing is to see if we can un-revert #3518, so the question is of whether #3518 is of sufficient value to bother. I wrote #3518 for fun rather than to satisfy a particular need that I have - I'm not actually a tokio user. I'm happy to have a go at test-infra, but not for it's own sake - only if it's actually providing someone with value. So it comes down to - is this something that will actually help people - for performance reasons, or otherwise? |
Generally, file reading involves a whole bunch of cross-thread communication with the current implementation, so it would surprise me if it doesn't help. I tried running the benchmarks in
Though it's just reading from |
Instead of probing the kernel version wouldn't it be better to do a normal read when reaching end of file to verify correct behavior? Since the file should be at its end the kernel should be able to serve the request without blocking unless something is appending to the file between the preadv2 and the read call. But if something else is concurrently writing to the file I would expect the some internal locks causing the threadpool fallback anyway. |
Closes: #3803
cc @br0adcast @wmanley