net_util: Use value returned from Queue::enable_notification()

This indicates if anything has been added to the available queue since
it was last iterated through. If it returns true then it is necessary to
iterate through the queue again otherwise it is appropriate to break out
from the loop.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-03-14 15:52:10 +00:00
parent 2ed0338da8
commit 1fc3fef642
2 changed files with 93 additions and 81 deletions

View File

@ -62,92 +62,98 @@ impl CtrlQueue {
access_platform: Option<&Arc<dyn AccessPlatform>>, access_platform: Option<&Arc<dyn AccessPlatform>>,
) -> Result<bool> { ) -> Result<bool> {
let mut used_desc_heads = Vec::new(); let mut used_desc_heads = Vec::new();
for mut desc_chain in queue.iter().map_err(Error::QueueIterator)? { loop {
let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?; for mut desc_chain in queue.iter().map_err(Error::QueueIterator)? {
let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?;
let ctrl_hdr: ControlHeader = desc_chain let ctrl_hdr: ControlHeader = desc_chain
.memory() .memory()
.read_obj( .read_obj(
ctrl_desc ctrl_desc
.addr() .addr()
.translate(access_platform, ctrl_desc.len() as usize), .translate(access_platform, ctrl_desc.len() as usize),
) )
.map_err(Error::GuestMemory)?; .map_err(Error::GuestMemory)?;
let data_desc = desc_chain.next().ok_or(Error::NoDataDescriptor)?; let data_desc = desc_chain.next().ok_or(Error::NoDataDescriptor)?;
let data_desc_addr = data_desc let data_desc_addr = data_desc
.addr() .addr()
.translate(access_platform, data_desc.len() as usize); .translate(access_platform, data_desc.len() as usize);
let status_desc = desc_chain.next().ok_or(Error::NoStatusDescriptor)?; let status_desc = desc_chain.next().ok_or(Error::NoStatusDescriptor)?;
let ok = match u32::from(ctrl_hdr.class) { let ok = match u32::from(ctrl_hdr.class) {
VIRTIO_NET_CTRL_MQ => { VIRTIO_NET_CTRL_MQ => {
let queue_pairs = desc_chain let queue_pairs = desc_chain
.memory() .memory()
.read_obj::<u16>(data_desc_addr) .read_obj::<u16>(data_desc_addr)
.map_err(Error::GuestMemory)?; .map_err(Error::GuestMemory)?;
if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET { if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd); warn!("Unsupported command: {}", ctrl_hdr.cmd);
false false
} else if (queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16) } else if (queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16)
|| (queue_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16) || (queue_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16)
{ {
warn!("Number of MQ pairs out of range: {}", queue_pairs); warn!("Number of MQ pairs out of range: {}", queue_pairs);
false false
} else { } else {
info!("Number of MQ pairs requested: {}", queue_pairs); info!("Number of MQ pairs requested: {}", queue_pairs);
true true
}
}
VIRTIO_NET_CTRL_GUEST_OFFLOADS => {
let features = desc_chain
.memory()
.read_obj::<u64>(data_desc_addr)
.map_err(Error::GuestMemory)?;
if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd);
false
} else {
let mut ok = true;
for tap in self.taps.iter_mut() {
info!("Reprogramming tap offload with features: {}", features);
tap.set_offload(virtio_features_to_tap_offload(features))
.map_err(|e| {
error!("Error programming tap offload: {:?}", e);
ok = false
})
.ok();
} }
ok
} }
} VIRTIO_NET_CTRL_GUEST_OFFLOADS => {
_ => { let features = desc_chain
warn!("Unsupported command {:?}", ctrl_hdr); .memory()
false .read_obj::<u64>(data_desc_addr)
} .map_err(Error::GuestMemory)?;
}; if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET {
warn!("Unsupported command: {}", ctrl_hdr.cmd);
false
} else {
let mut ok = true;
for tap in self.taps.iter_mut() {
info!("Reprogramming tap offload with features: {}", features);
tap.set_offload(virtio_features_to_tap_offload(features))
.map_err(|e| {
error!("Error programming tap offload: {:?}", e);
ok = false
})
.ok();
}
ok
}
}
_ => {
warn!("Unsupported command {:?}", ctrl_hdr);
false
}
};
desc_chain desc_chain
.memory() .memory()
.write_obj( .write_obj(
if ok { VIRTIO_NET_OK } else { VIRTIO_NET_ERR } as u8, if ok { VIRTIO_NET_OK } else { VIRTIO_NET_ERR } as u8,
status_desc status_desc
.addr() .addr()
.translate(access_platform, status_desc.len() as usize), .translate(access_platform, status_desc.len() as usize),
) )
.map_err(Error::GuestMemory)?; .map_err(Error::GuestMemory)?;
let len = ctrl_desc.len() + data_desc.len() + status_desc.len(); let len = ctrl_desc.len() + data_desc.len() + status_desc.len();
used_desc_heads.push((desc_chain.head_index(), len)); used_desc_heads.push((desc_chain.head_index(), len));
} }
for (desc_index, len) in used_desc_heads.iter() { for (desc_index, len) in used_desc_heads.iter() {
queue queue
.add_used(*desc_index, *len) .add_used(*desc_index, *len)
.map_err(Error::QueueAddUsed)?; .map_err(Error::QueueAddUsed)?;
queue }
if !queue
.enable_notification() .enable_notification()
.map_err(Error::QueueEnableNotification)?; .map_err(Error::QueueEnableNotification)?
{
break;
}
} }
Ok(!used_desc_heads.is_empty()) Ok(!used_desc_heads.is_empty())

View File

@ -130,9 +130,12 @@ impl TxVirtio {
queue queue
.add_used(used_desc_head.0, used_desc_head.1) .add_used(used_desc_head.0, used_desc_head.1)
.map_err(NetQueuePairError::QueueAddUsed)?; .map_err(NetQueuePairError::QueueAddUsed)?;
queue if !queue
.enable_notification() .enable_notification()
.map_err(NetQueuePairError::QueueEnableNotification)?; .map_err(NetQueuePairError::QueueEnableNotification)?
{
break;
}
} }
Ok(retry_write) Ok(retry_write)
@ -275,9 +278,12 @@ impl RxVirtio {
queue queue
.add_used(used_desc_head.0, used_desc_head.1) .add_used(used_desc_head.0, used_desc_head.1)
.map_err(NetQueuePairError::QueueAddUsed)?; .map_err(NetQueuePairError::QueueAddUsed)?;
queue if !queue
.enable_notification() .enable_notification()
.map_err(NetQueuePairError::QueueEnableNotification)?; .map_err(NetQueuePairError::QueueEnableNotification)?
{
break;
}
} }
Ok(exhausted_descs) Ok(exhausted_descs)