-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
cpu load by prepare_uninitialized_buffer in async_read of tokio-io #269
Comments
Do you know which type’s AsyncRead implementation is doing this? |
Actually I am not sure, which of those is used via the websocket crate. I am using websocket with TlsStream aka a wss:// address. Independent from this, manually zeroing should be avoided in general. Perhaps using bytes::BytesMut in tokio-io would avoid this problem totally. As I understand, zeroing is exclusively used to avoid lack of sensitive data (which I doubt makes sense in this context). In the meantime I have solved it by avoiding tokio and the websocket-future. Instead I am using the sync-version of the websocket. Now the CPU load of the application is OK. |
The issue is most likely that some type that implements |
i just did a quick search through the perhaps this needs to be updated to proxy calls onto the reader? |
If this would be sufficient, then IMHO overriding prepare_uninitialized() like below should help impl<R, W> AsyncRead for ReadWritePair<R, W>
where R: AsyncRead,
W: Write
{
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
false
}
} But it doesn't. I have tried without effect:
If the CPU hogging can be fixed in websocket, then I can raise an issue there. But I think, the zeroing is not good in tokio-io in the first place. |
Zeroing out is required for safety. It would be unsafe to pass in uninitialized memory. This is why implementations of If all your |
Why? It is forbidden to |
@kpp The problem is that it is technically possible to read the data in a |
It is not forbidden by the compiler. This is the problem. |
Why not use one of these alternatives:
Anyway I do not understand the problem in this case. The malicious user is the application tokio-io is linked in. If it cannot be trusted, then what else to trust ? BTW: If the tokio-io user (aka websocket crate) has a means to avoid the zeroing, then I miss totally the point of safety. If the application cannot be trusted, then for sure the application will not use tokio-io's zeroing. If it is about safety for the application, then application should not use unsafe ways to read out data outside of the filled in data in the BufMut |
👍 |
@gin66 The malicious user is not the application using tokio-io When safety is discussed here, it is in terms of Rust's memory model. Informally, when writing Rust code, it should be impossible to be able to read uninitialized memory without writing However, this discussion isn't limited to Tokio, and if you wish to continue it, I'd recommend rust-lang/rust#42788. Tokio will end up following what the Rust team goes with. |
@carllerche Thanks for clarification. Before I have thought, that BufMut prohibits access to uninitialized area except My current solution is to use the synchronous version of websocket and enjoy single digit CPU load. For me is OK to wait for that rust-discussion and close this issue here. |
@gin66 To be clear, if large amounts of CPU is being used to zero out memory, it is a bug, but it would be in the library that has a type that incorrectly implements |
Sorry for posting in a closed issue, but I have the same problem:
(Yes, I use I'd like to continue to use the async version of websocket crate though.
As stated before in the websocket implementation of |
@hweom it needs to delegate |
I ran into the same problem with the websockets lib earlier today and after a good amount of profiling and debugging, I figured out that:
When adding a |
The current implementation zeros out a buffer, which consumes a lot of time. In my application the CPU actually spends 86% in this routine, which only listens to a tls web socket stream. The traffic is not high (10-100 kB/s), but this buffer zeroing has a huge hit on the application performance.
The application makes use of the websocket crate, which imports tokio-io. It uses the framed interface, so the application has no direct access. Possibly there could be some (complex) solution be implemented to solve this problem. Best would be to add a feature-flag, which decides about zero out the buffer or not.
Any other solution ?
The text was updated successfully, but these errors were encountered: