block: make available VIRTIO_BLK_F_SEG_MAX

This allows the guest to put in more than one segment per request. It
can improve the throughput of the system.

Introduce a new check to make sure the queue size configured by the user
is large enough to hold at least one segment.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu 2024-12-21 00:38:10 +00:00 committed by Rob Bradford
parent 6fd5b0f696
commit 32482f6634
2 changed files with 17 additions and 0 deletions

View File

@ -56,6 +56,8 @@ const RATE_LIMITER_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 3;
// latency scale, for reduce precision loss in calculate.
const LATENCY_SCALE: u64 = 10000;
pub const MINIMUM_BLOCK_QUEUE_SIZE: u16 = 2;
#[derive(Error, Debug)]
pub enum Error {
#[error("Failed to parse the request: {0}")]
@ -625,6 +627,7 @@ impl Block {
| (1u64 << VIRTIO_BLK_F_CONFIG_WCE)
| (1u64 << VIRTIO_BLK_F_BLK_SIZE)
| (1u64 << VIRTIO_BLK_F_TOPOLOGY)
| (1u64 << VIRTIO_BLK_F_SEG_MAX)
| (1u64 << VIRTIO_RING_F_EVENT_IDX)
| (1u64 << VIRTIO_RING_F_INDIRECT_DESC);
if iommu {
@ -660,6 +663,7 @@ impl Block {
physical_block_exp,
min_io_size: (topology.minimum_io_size / logical_block_size) as u16,
opt_io_size: (topology.optimal_io_size / logical_block_size) as u32,
seg_max: (queue_size - MINIMUM_BLOCK_QUEUE_SIZE) as u32,
..Default::default()
};

View File

@ -14,6 +14,7 @@ use option_parser::{
};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use virtio_devices::block::MINIMUM_BLOCK_QUEUE_SIZE;
use virtio_devices::{RateLimiterConfig, TokenBucketConfig};
use crate::landlock::LandlockAccess;
@ -168,6 +169,8 @@ pub enum ValidationError {
TdxFirmwareMissing,
/// Insufficient vCPUs for queues
TooManyQueues,
/// Invalid queue size
InvalidQueueSize(u16),
/// Need shared memory for vfio-user
UserDevicesRequireSharedMemory,
/// VSOCK Context Identifier has a special meaning, unsuitable for a VM.
@ -273,6 +276,12 @@ impl fmt::Display for ValidationError {
TooManyQueues => {
write!(f, "Number of vCPUs is insufficient for number of queues")
}
InvalidQueueSize(s) => {
write!(
f,
"Queue size is smaller than {MINIMUM_BLOCK_QUEUE_SIZE}: {s}"
)
}
UserDevicesRequireSharedMemory => {
write!(
f,
@ -1307,6 +1316,10 @@ impl DiskConfig {
return Err(ValidationError::TooManyQueues);
}
if self.queue_size <= MINIMUM_BLOCK_QUEUE_SIZE {
return Err(ValidationError::InvalidQueueSize(self.queue_size));
}
if self.vhost_user && self.iommu {
return Err(ValidationError::IommuNotSupported);
}