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 Oct 23, 2024
1 parent 7bf7394 commit f568ea1
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 f568ea1

Please sign in to comment.