mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 00:43:24 +00:00
Remove add_buf from VirtQueue
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
2256f6ae8a
commit
a482c87696
@ -1,12 +1,10 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use alloc::{boxed::Box, string::ToString, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, string::ToString, sync::Arc};
|
||||||
use core::{fmt::Debug, hint::spin_loop, mem::size_of};
|
use core::{fmt::Debug, hint::spin_loop, mem::size_of};
|
||||||
|
|
||||||
use aster_frame::{offset_of, sync::SpinLock, trap::TrapFrame};
|
use aster_frame::{offset_of, sync::SpinLock, trap::TrapFrame};
|
||||||
use aster_network::{
|
use aster_network::{AnyNetworkDevice, EthernetAddr, RxBuffer, TxBuffer, VirtioNetError};
|
||||||
AnyNetworkDevice, EthernetAddr, NetDeviceIrqHandler, RxBuffer, TxBuffer, VirtioNetError,
|
|
||||||
};
|
|
||||||
use aster_util::{field_ptr, slot_vec::SlotVec};
|
use aster_util::{field_ptr, slot_vec::SlotVec};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use smoltcp::phy::{DeviceCapabilities, Medium};
|
use smoltcp::phy::{DeviceCapabilities, Medium};
|
||||||
@ -24,7 +22,6 @@ pub struct NetworkDevice {
|
|||||||
send_queue: VirtQueue,
|
send_queue: VirtQueue,
|
||||||
recv_queue: VirtQueue,
|
recv_queue: VirtQueue,
|
||||||
rx_buffers: SlotVec<RxBuffer>,
|
rx_buffers: SlotVec<RxBuffer>,
|
||||||
callbacks: Vec<Box<dyn NetDeviceIrqHandler>>,
|
|
||||||
transport: Box<dyn VirtioTransport>,
|
transport: Box<dyn VirtioTransport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +73,6 @@ impl NetworkDevice {
|
|||||||
recv_queue,
|
recv_queue,
|
||||||
rx_buffers,
|
rx_buffers,
|
||||||
transport,
|
transport,
|
||||||
callbacks: Vec::new(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Interrupt handler if network device config space changes
|
/// Interrupt handler if network device config space changes
|
||||||
@ -220,4 +216,3 @@ const QUEUE_RECV: u16 = 0;
|
|||||||
const QUEUE_SEND: u16 = 1;
|
const QUEUE_SEND: u16 = 1;
|
||||||
|
|
||||||
const QUEUE_SIZE: u16 = 64;
|
const QUEUE_SIZE: u16 = 64;
|
||||||
const RX_BUFFER_LEN: usize = 4096;
|
|
||||||
|
@ -226,77 +226,6 @@ impl VirtQueue {
|
|||||||
Ok(head)
|
Ok(head)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add buffers to the virtqueue, return a token. **This function will be removed in the future.**
|
|
||||||
///
|
|
||||||
/// Ref: linux virtio_ring.c virtqueue_add
|
|
||||||
pub fn add_buf(&mut self, inputs: &[&[u8]], outputs: &[&mut [u8]]) -> Result<u16, QueueError> {
|
|
||||||
// FIXME: use `DmaSteam` for inputs and outputs. Now because the upper device driver lacks the
|
|
||||||
// ability to safely construct DmaStream from slice, slice is still used here.
|
|
||||||
// pub fn add(
|
|
||||||
// &mut self,
|
|
||||||
// inputs: &[&DmaStream],
|
|
||||||
// outputs: &[&mut DmaStream],
|
|
||||||
// ) -> Result<u16, QueueError> {
|
|
||||||
|
|
||||||
if inputs.is_empty() && outputs.is_empty() {
|
|
||||||
return Err(QueueError::InvalidArgs);
|
|
||||||
}
|
|
||||||
if inputs.len() + outputs.len() + self.num_used as usize > self.queue_size as usize {
|
|
||||||
return Err(QueueError::BufferTooSmall);
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate descriptors from free list
|
|
||||||
let head = self.free_head;
|
|
||||||
let mut last = self.free_head;
|
|
||||||
for input in inputs.iter() {
|
|
||||||
let desc = &self.descs[self.free_head as usize];
|
|
||||||
set_buf_slice(&desc.borrow_vm().restrict::<TRights![Write, Dup]>(), input);
|
|
||||||
field_ptr!(desc, Descriptor, flags)
|
|
||||||
.write(&DescFlags::NEXT)
|
|
||||||
.unwrap();
|
|
||||||
last = self.free_head;
|
|
||||||
self.free_head = field_ptr!(desc, Descriptor, next).read().unwrap();
|
|
||||||
}
|
|
||||||
for output in outputs.iter() {
|
|
||||||
let desc = &mut self.descs[self.free_head as usize];
|
|
||||||
set_buf_slice(&desc.borrow_vm().restrict::<TRights![Write, Dup]>(), output);
|
|
||||||
field_ptr!(desc, Descriptor, flags)
|
|
||||||
.write(&(DescFlags::NEXT | DescFlags::WRITE))
|
|
||||||
.unwrap();
|
|
||||||
last = self.free_head;
|
|
||||||
self.free_head = field_ptr!(desc, Descriptor, next).read().unwrap();
|
|
||||||
}
|
|
||||||
// set last_elem.next = NULL
|
|
||||||
{
|
|
||||||
let desc = &mut self.descs[last as usize];
|
|
||||||
let mut flags: DescFlags = field_ptr!(desc, Descriptor, flags).read().unwrap();
|
|
||||||
flags.remove(DescFlags::NEXT);
|
|
||||||
field_ptr!(desc, Descriptor, flags).write(&flags).unwrap();
|
|
||||||
}
|
|
||||||
self.num_used += (inputs.len() + outputs.len()) as u16;
|
|
||||||
|
|
||||||
let avail_slot = self.avail_idx & (self.queue_size - 1);
|
|
||||||
|
|
||||||
{
|
|
||||||
let ring_ptr: SafePtr<[u16; 64], &DmaCoherent> =
|
|
||||||
field_ptr!(&self.avail, AvailRing, ring);
|
|
||||||
let mut ring_slot_ptr = ring_ptr.cast::<u16>();
|
|
||||||
ring_slot_ptr.add(avail_slot as usize);
|
|
||||||
ring_slot_ptr.write(&head).unwrap();
|
|
||||||
}
|
|
||||||
// write barrier
|
|
||||||
fence(Ordering::SeqCst);
|
|
||||||
|
|
||||||
// increase head of avail ring
|
|
||||||
self.avail_idx = self.avail_idx.wrapping_add(1);
|
|
||||||
field_ptr!(&self.avail, AvailRing, idx)
|
|
||||||
.write(&self.avail_idx)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
fence(Ordering::SeqCst);
|
|
||||||
Ok(head)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether there is a used element that can pop.
|
/// Whether there is a used element that can pop.
|
||||||
pub fn can_pop(&self) -> bool {
|
pub fn can_pop(&self) -> bool {
|
||||||
// read barrier
|
// read barrier
|
||||||
@ -421,6 +350,8 @@ type DescriptorPtr<'a> = SafePtr<Descriptor, &'a DmaCoherent, TRightSet<TRights!
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_dma_buf<T: DmaBuf>(desc_ptr: &DescriptorPtr, buf: &T) {
|
fn set_dma_buf<T: DmaBuf>(desc_ptr: &DescriptorPtr, buf: &T) {
|
||||||
|
// TODO: skip the empty dma buffer or just return error?
|
||||||
|
debug_assert_ne!(buf.len(), 0);
|
||||||
let daddr = buf.daddr();
|
let daddr = buf.daddr();
|
||||||
field_ptr!(desc_ptr, Descriptor, addr)
|
field_ptr!(desc_ptr, Descriptor, addr)
|
||||||
.write(&(daddr as u64))
|
.write(&(daddr as u64))
|
||||||
@ -430,21 +361,6 @@ fn set_dma_buf<T: DmaBuf>(desc_ptr: &DescriptorPtr, buf: &T) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
fn set_buf_slice(desc_ptr: &DescriptorPtr, buf: &[u8]) {
|
|
||||||
// FIXME: use `DmaSteam` for buf. Now because the upper device driver lacks the
|
|
||||||
// ability to safely construct DmaStream from slice, slice is still used here.
|
|
||||||
let va = buf.as_ptr() as usize;
|
|
||||||
let pa = aster_frame::vm::vaddr_to_paddr(va).unwrap();
|
|
||||||
field_ptr!(desc_ptr, Descriptor, addr)
|
|
||||||
.write(&(pa as u64))
|
|
||||||
.unwrap();
|
|
||||||
field_ptr!(desc_ptr, Descriptor, len)
|
|
||||||
.write(&(buf.len() as u32))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Descriptor flags
|
/// Descriptor flags
|
||||||
#[derive(Pod, Default)]
|
#[derive(Pod, Default)]
|
||||||
|
Reference in New Issue
Block a user