Skip to content

Commit

Permalink
virtio-serial: pop all the received data
Browse files Browse the repository at this point in the history
Pop all the received data from port queue and virtio queue and try to
fill the caller's buffer as much as possible after receiving from virtio
serial device.

Signed-off-by: Jiaqi Gao <[email protected]>
  • Loading branch information
gaojiaqi7 committed Nov 12, 2024
1 parent 0646a9a commit f59f92d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/devices/virtio_serial/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,18 @@ impl VirtioSerial {
fn port_queue_pop(port_id: u32) -> Option<Vec<u8>> {
RECEIVE_QUEUES.lock().get_mut(&port_id)?.pop_front()
}

fn can_recv(&self, port_id: u32) -> bool {
RECEIVE_QUEUES
.lock()
.get(&port_id)
.is_some_and(|q| !q.is_empty())
|| self
.queues
.index(Self::port_queue_index(port_id) as usize)
.borrow_mut()
.can_pop()
}
}

/// Align `size` up to a page.
Expand Down
29 changes: 20 additions & 9 deletions src/devices/virtio_serial/src/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,37 @@ impl VirtioSerialPort {

pub fn recv(&mut self, data: &mut [u8]) -> Result<usize> {
if self.cache.is_empty() {
let recv_bytes = SERIAL_DEVICE
.lock()
.get_mut()
.ok_or(VirtioSerialError::InvalidParameter)?
.dequeue(self.port_id, DEFAULT_TIMEOUT)?;
self.cache.push_back(recv_bytes);
loop {
let recv_bytes = SERIAL_DEVICE
.lock()
.get_mut()
.ok_or(VirtioSerialError::InvalidParameter)?
.dequeue(self.port_id, DEFAULT_TIMEOUT)?;
self.cache.push_back(recv_bytes);

if !SERIAL_DEVICE
.lock()
.get_mut()
.ok_or(VirtioSerialError::InvalidParameter)?
.can_recv(self.port_id)
{
break;
}
}
}

let mut recvd = 0;
if !self.cache.is_empty() {
while !self.cache.is_empty() {
let front = self.cache.front_mut().unwrap();
let expect = data.len() - recvd;
if front.len() <= expect {
data[..front.len()].copy_from_slice(front);
data[recvd..recvd + front.len()].copy_from_slice(front);
recvd += front.len();
self.cache.pop_front();
} else {
data[recvd..].copy_from_slice(&front[..expect]);
front.drain(..expect);
recvd = expect;
recvd += expect;
}
}

Expand Down

0 comments on commit f59f92d

Please sign in to comment.