virtio-blk: add discard request support - #6142
Conversation
5d91a17 to
9da880c
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6142 +/- ##
==========================================
- Coverage 83.03% 82.97% -0.07%
==========================================
Files 277 277
Lines 31123 31254 +131
==========================================
+ Hits 25844 25933 +89
- Misses 5279 5321 +42
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
9da880c to
09dd359
Compare
09dd359 to
f05fee0
Compare
8e495da to
c9f0926
Compare
| /// Maximum sectors accepted in a single discard range. | ||
| /// | ||
| /// Keep this bounded so guest fstrim is split into predictable chunks instead | ||
| /// of letting one large discard ioctl block the VMM thread for too long. | ||
| pub const MAX_DISCARD_SECTORS: u32 = (128_u32 << 20) / SECTOR_SIZE; | ||
| /// Maximum number of segments accepted in a single discard request. | ||
| pub const MAX_DISCARD_SEG: u32 = 1; | ||
| /// Discard alignment, expressed in 512-byte sectors. | ||
| pub const DISCARD_SECTOR_ALIGNMENT: u32 = 1; |
There was a problem hiding this comment.
Since other defaults for the ConfigSpace are in the default impl, we better move these there as well.
There was a problem hiding this comment.
done, just kept MAX_DISCARD_SECTORS as it's also used in request.rs
| } else if config.discard { | ||
| avail_features |= 1u64 << VIRTIO_BLK_F_DISCARD; |
There was a problem hiding this comment.
I would move this out of else branch so just
if config.is_read_only {
...
}
if config.discard {
...
}Since the check for is_read_only && discrard is just a couple lines above
| config_space.discard_sector_alignment = | ||
| query_discard_alignment(disk_properties.file_engine.file()) | ||
| .map_err(|err| { | ||
| VirtioBlockError::BackingFile(err, disk_properties.file_path.clone()) | ||
| })? | ||
| .to_le(); |
There was a problem hiding this comment.
I don's see why you need to separately query alignment here.
Instead this logic should just be in a code bellow:
if config.blk_size.is_none() && config.topology.is_none() {
if let Some((blk_size, topology)) = query_blk_attrs(disk_properties.file_engine.file())
.and_then(calculate_blk_size_and_topology)
{
config_space.blk_size = blk_size;
config_space.topology = topology;
config_space.discard_sector_alignment = blk_size / SECTOR_SIZE;
}
} else {
if let Some(blk_size) = config.blk_size {
config_space.blk_size = blk_size;
config_space.discard_sector_alignment = blk_size / SECTOR_SIZE;
}
if let Some(topology) = config.topology {
config_space.topology = topology;
}
}We can leave if blk_size < SECTOR_SIZE || !blk_size.is_multiple_of(SECTOR_SIZE) { out for now since we already don't have this check.
There was a problem hiding this comment.
If the user specify only topology then we never set the discard_sector_alignment correctly and I'd also prefer to query rather than trust the user to put the correct blk_size?
There was a problem hiding this comment.
well, the reason we expose blk_size to the user is for them to configure it however they want. I think it is reasonable to only query if user did not provide anything. This is the current behavior we have anyway.
There was a problem hiding this comment.
applied code suggestion, removed query helper
| )?; | ||
| self.config_space.capacity = self.disk.nsectors.to_le(); // virtio_block_config_space(); | ||
| if let Some(new_discard_alignment) = new_discard_alignment { | ||
| self.config_space.discard_sector_alignment = new_discard_alignment.to_le(); |
There was a problem hiding this comment.
Guest will only check the capacity field on the config update, so there is no reason to do this dance with querying new alignment.
There was a problem hiding this comment.
The query new alignment check is to ensure that the new disk alignment divides the previous disk alignment otherwise the guest can submit valid discard requests that the new backend rejects.
There was a problem hiding this comment.
It is fine if guest will reject them. We will detect this and report to the guest about the failures. It is user responsibility to replace backing file with something that has same logical size and so same discard alignment. We should add this to the doc I think.
There was a problem hiding this comment.
removed alignment check, updated doc accordingly
| max_discard_sectors: MAX_DISCARD_SECTORS.to_le(), | ||
| max_discard_seg: MAX_DISCARD_SEG.to_le(), | ||
| discard_sector_alignment: DISCARD_SECTOR_ALIGNMENT.to_le(), |
There was a problem hiding this comment.
also more of a nit: we are on little endian anyway, so no reason to call to_le
| let discard_sector_alignment = if avail_features & (1u64 << VIRTIO_BLK_F_DISCARD) != 0 { | ||
| query_discard_alignment(disk_properties.file_engine.file()) | ||
| .map_err(|err| VirtioBlockError::BackingFile(err, state.disk_path.clone()))? | ||
| } else { | ||
| DISCARD_SECTOR_ALIGNMENT | ||
| }; |
There was a problem hiding this comment.
just store state.virtio_state.discard_sector_alignment directly
| new VIRTIO_BLK_F_BLK_SIZE and VIRTIO_BLK_F_TOPOLOGY features to the | ||
| virtio-block device. More information is in the new [block](docs/block.md) | ||
| documentation. | ||
| - [#5908](https://github.com/firecracker-microvm/firecracker/pull/5908): Add |
There was a problem hiding this comment.
If we are touching this PR anyway, how about moving CHANGELOG and docs changes into a separate commits?
Extend the virtio-blk config space through the discard limit fields so the device can report discard capability details when the feature is enabled. [jackabt@amazon.com: rebased onto main and reconciled with the read-only config space test] Signed-off-by: Jonas Savulionis <jonas@esnet.lt> Signed-off-by: Jack Thomson <jackabt@amazon.com>
Add opt-in virtio-blk discard support for sync file-backed drives. The device advertises VIRTIO_BLK_F_DISCARD only when enabled, validates guest discard ranges once during request parsing, and executes discard through BLKDISCARD for block devices or fallocate hole punching for regular files. Derive discard alignment from the logical block size advertised to the guest and persist that alignment across snapshot restore. Disk image updates retain the original value. Reject discard for read-only drives and the async IO engine for now, and return UNSUPP if a guest submits discard without negotiating the feature. [jackabt@amazon.com: rebased onto main and updated the config round-trip expectations for the normalised discard field in test_block_config, resources, and the two device manager persistence tests] Signed-off-by: Jonas Savulionis <jonas@esnet.lt> Signed-off-by: Rekas <aure369@gmail.com> Signed-off-by: Jack Thomson <jackabt@amazon.com> Signed-off-by: Pierre Bertholom <pbertho@amazon.com>
Allow the sync virtio-blk discard path to punch holes in regular files and issue BLKDISCARD for block-device backed drives. [jackabt@amazon.com: rebased onto main] Signed-off-by: Jonas Savulionis <jonas@esnet.lt> Signed-off-by: Rekas <aure369@gmail.com> Signed-off-by: Jack Thomson <jackabt@amazon.com>
Cover the discard drive API by validating successful configuration, guest-visible discard granularity, and rejection of unsupported read-only or async combinations. Add a guest functional test that writes data to a file-backed drive, issues blkdiscard, and verifies host block allocation decreases. [jackabt@amazon.com: rebased onto main] Signed-off-by: Jonas Savulionis <jonas@esnet.lt> Signed-off-by: Rekas <aure369@gmail.com> Signed-off-by: Jack Thomson <jackabt@amazon.com> Signed-off-by: Pierre Bertholom <pbertho@amazon.com>
c9f0926 to
8d3fb21
Compare
Document the supported discard configurations, advertised alignment rules, and user responsibility for compatible block device updates. Add the feature to the changelog. [jackabt@amazon.com: rebased onto main and moved the changelog entry to the unreleased section] Signed-off-by: Jonas Savulionis <jonas@esnet.lt> Signed-off-by: Rekas <aure369@gmail.com> Signed-off-by: Jack Thomson <jackabt@amazon.com> Signed-off-by: Pierre Bertholom <pbertho@amazon.com>
8d3fb21 to
8765668
Compare
Changes
Update of the PR: #5908
To fix a few warning and update against main
Also fixed a bug in which the config space was no longer calling
.to_le()Reason
...
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 checkbuild --allto verify that the PR passesbuild checks on all supported architectures.
tools/devtool checkstyleto 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.