-
Notifications
You must be signed in to change notification settings - Fork 2k
Fix greedy block device #5260
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
Fix greedy block device #5260
Conversation
f896954
to
90bd921
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5260 +/- ##
==========================================
+ Coverage 82.84% 82.88% +0.03%
==========================================
Files 250 250
Lines 26967 26968 +1
==========================================
+ Hits 22342 22352 +10
+ Misses 4625 4616 -9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
So the virtio spec says
2.6.7.2 Device Requirements: Used Buffer Notification Suppression
If the VIRTIO_F_EVENT_IDX feature bit is not negotiated:
- The device MUST ignore the used_event value.
- After the device writes a descriptor index into the used ring:
- If flags is 1, the device SHOULD NOT send a notification.
- If flags is 0, the device MUST send a notification.
Otherwise, if the VIRTIO_F_EVENT_IDX feature bit is negotiated:
- The device MUST ignore the lower bit of flags.
- After the device writes a descriptor index into the used ring:
- If the idx field in the used ring (which determined where that descriptor index was placed) was equal to used_event, the device MUST send a notification.
- Otherwise the device SHOULD NOT send a notification.
So if the guest doesnt accept the VIRTIO_F_EVENT_IDX feature bit, then we must send notifications as we do today (e.g. without this PR), immediately after every time we write to the used ring. So in that sense, I don't think this is correct :/
But we do send a notification, just a bit later :) I think the spirit of this Saying these, it made me thinking that it might be the case that guest only adds descriptors that (if consumed all) would reach the |
...mh, I guess the spec is indeed a bit vague here, but I interpreted the "after" as "immediately after". But I can totally see your interpretation as well now. I guess in this case, if it works on linux... |
spec vague, will defer to "it works with linux guests"
b6c2b77
to
56f93de
Compare
The `max_size` field is public, so no need for a getter. Signed-off-by: Egor Lazarchuk <[email protected]>
The size of queue set by the driver must be always less or equal to the queue size in FC. This is checked before device activation. This removes the need for `actual_size` function. Signed-off-by: Egor Lazarchuk <[email protected]>
d590ff9
to
9eedd55
Compare
Currently block device has a guest notification logic inside it's request processing loop. This can create a situation when guest can continuously add more requests to the queue, making the whole request processing loop arbitrary long. This is an issue, since it block any other IO from being processed. The solution is to simply notify guest one time, after all current requests are processed. Signed-off-by: Egor Lazarchuk <[email protected]> Signed-off-by: Riccardo Mancini <[email protected]>
VIRTIO spec states: ``` After the device writes a descriptor index into the used ring: If the idx field in the used ring (which determined where that descriptor index was placed) was equal to used_event, the device MUST send a notification. ``` The current implementation does not follow this very precisely. It bumps used ring index when new descriptors are added to the used ring. But the check if the notification is needed is postponed to later processing stage. To be more VIRTIO spec compliant simply move the logic for updating the used ring index into the later processing stage as well, just before the check if the notification should be send. Signed-off-by: Egor Lazarchuk <[email protected]>
usize cannot be negative Signed-off-by: Egor Lazarchuk <[email protected]>
Add a new changelog entry for the block device fairness fix. Signed-off-by: Riccardo Mancini <[email protected]>
9eedd55
to
2aa4f12
Compare
Changes
add_used
call to be more VIRTIO spec compliant.Reason
We discovered a bug where a sufficiently slow drive could cause the IO thread to get stuck processing block device request indefinitely, thus starving all other devices.
This is caused by the guest driver adding new descriptors to the virtio queue while the device is still processing them, leading to an indefinite loop.
The fix is to only update the used index and send a notification to the guest driver only once all descriptors have been processed by the device. This mitigates the issue by bounding the amount of time spent in processing block device requests, allowing other devices to complete their work as well.
License Acceptance
By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following Developer
Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md
.PR Checklist
tools/devtool checkstyle
to verify that the PR passes theautomated style checks.
how they are solving the problem in a clear and encompassing way.
in the PR.
CHANGELOG.md
.Runbook for Firecracker API changes.
integration tests.
TODO
.rust-vmm
.