Skip to content
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

[vsock] Add method to send credit update manually #110

Merged
merged 8 commits into from
Sep 15, 2023

Conversation

aliciawyy
Copy link
Contributor

This PR addresses a bug in the vsock connection manager. Prior to the PR, the guest doesn't update the host after it processes the local buffer. As a result, when the receiving message length reaches the buffer capacity, the host could mistakenly stop sending the message, unaware that the guest still had available buffer.

This fix ensures that the credit is correctly updated after processing the local buffer, allowing for continuous message transmission between the host and the guest.

Alice Wang added 3 commits August 24, 2023 09:01
This PR addresses a bug in the vsock connection manager. Prior to
the PR, the guest doesn't update the host after it processes the
local buffer. As a result, when the receiving message length
reaches its buffer capacity, the host could mistakenly stop
sending the message, unaware that the guest still had available
buffer.
This fix ensures that the credit is correctly updated processing
the local buffer, allowing for continuous message transmission
between the host and the guest.
@aliciawyy
Copy link
Contributor Author

It looks like there's some connection issues with clippy in CI. Can someone take a look at this PR?

connection.info.done_forwarding(bytes_read);
if bytes_read > 0 {
connection.info.done_forwarding(bytes_read);
self.driver.credit_update(&connection.info)?;
Copy link
Collaborator

@qwandor qwandor Aug 30, 2023

Choose a reason for hiding this comment

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

I don't think this is a good idea. It makes what was previously a non-blocking call (except in the case that the connection is in the process of shutdown) into a blocking call. This will significantly reduce performance, especially if the client is calling recv many times in a row with small buffers. It's also sending lots of credit updates that the host didn't ask for, which while allowed by the specification is unnecessary and will fill up the transmit queue and waste time on the host.

Credit is already updated for the connection whenever we send anything else on it (e.g. sending some data), which is likely to be enough a fair bit of the time in practice. If the host is blocked waiting for credit then it should send a credit request, which VsockConnectionManager::poll will automatically respond to. So all the client needs to do is ensure they are regularly calling poll, which is anyway necessary to avoid other deadlocks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Credit is already updated for the connection whenever we send anything else on it (e.g. sending some data), which is likely to be enough a fair bit of the time in practice.

That's true. But it is still blocked when the guest just wants to receive a message longer than 1024 bytes and it sends nothing to the host till it receives the whole message.

If the host is blocked waiting for credit then it should send a credit request ...

It looks like in practice the host doesn't always send credit request when it gets blocked. You can reproduce the failure without this fix by increasing the message length in this test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about I just add a new API to update the credit to allow users to call it by themselves?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, that's weird. Are you seeing this behaviour both with QEMU and crosvm?

Adding an API to send an unrequested credit update is alright I guess. I still think you shouldn't call it for every receive, as that will have a significant impact on performance. Perhaps you could just call it once you've emptied the receive buffer? To achieve that you could expose a new method on VsockConnectionManager to return the number of bytes currently in the receive buffer (perhaps call it available), and if after receiving a non-zero number of bytes available returns 0, then you know that the buffer has just become empty. Further optimisations are probably possible.

Copy link
Contributor Author

@aliciawyy aliciawyy Sep 4, 2023

Choose a reason for hiding this comment

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

There appears to be a potential issue with the driver itself, as both crosvm and qemu are experiencing a bug when sending long messages. However, it's worth noting that the problem encountered in qemu is slightly different. To test this issue with qemu, I modified the message sent from the host to be 3000 bytes long and adjusted the receiver buffer accordingly. As a result, the following error was observed on the host:

thread 'main' panicked at 'write_all: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }', src/main.rs:31:14

@qwandor qwandor changed the title [vsock] Fix credit update in recv() to ensure message transimission [vsock] Add method to send credit update manually Sep 4, 2023
@@ -226,6 +226,18 @@ impl<H: Hal, T: Transport> VsockConnectionManager<H, T> {
Ok(bytes_read)
}

/// Returns whether the receive buffer is empty.
pub fn is_recv_buffer_empty(&mut self, peer: VsockAddr, src_port: u32) -> Result<bool> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think an available method which returns the number of bytes available to read (as I was suggesting before) would be better, as it's useful for other things as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@qwandor qwandor merged commit 321e56a into rcore-os:master Sep 15, 2023
5 checks passed
@aliciawyy aliciawyy deleted the wipFix branch September 15, 2023 15:07
@aliciawyy
Copy link
Contributor Author

Hi @qwandor can we release a new patch with these APIs?

@qwandor
Copy link
Collaborator

qwandor commented Sep 25, 2023

Hi @qwandor can we release a new patch with these APIs?

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants