Skip to content

Commit

Permalink
fix: combine enable_dev_notify and disable_dev_notify
Browse files Browse the repository at this point in the history
  • Loading branch information
hky1999 committed Nov 12, 2023
1 parent 574d692 commit 8f288ea
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/device/net/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::net_buf::{RxBuffer, TxBuffer};
use super::{EthernetAddress, VirtIONetRaw};
use crate::{hal::Hal, transport::Transport, Error, Result};

/// Driver for a VirtIO block device.
/// Driver for a VirtIO network device.
///
/// Unlike [`VirtIONetRaw`], it uses [`RxBuffer`]s for transmission and
/// reception rather than the raw slices. On initialization, it pre-allocates
Expand Down
16 changes: 8 additions & 8 deletions src/device/net/dev_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONetRaw<H, T, QUEUE_SIZ

/// Disable interrupts.
pub fn disable_interrupts(&mut self) {
self.send_queue.disable_dev_notify();
self.recv_queue.disable_dev_notify();
self.send_queue.set_dev_notify(false);
self.recv_queue.set_dev_notify(false);
}

/// Enable interrupts.
pub fn enable_interrupts(&mut self) {
self.send_queue.enable_dev_notify();
self.recv_queue.enable_dev_notify();
self.send_queue.set_dev_notify(true);
self.recv_queue.set_dev_notify(true);
}

/// Get MAC address.
Expand Down Expand Up @@ -172,7 +172,7 @@ impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONetRaw<H, T, QUEUE_SIZ
///
/// # Safety
///
/// The same buffers must be passed in again as were passed to
/// The same buffer must be passed in again as were passed to
/// [`transmit_begin`] when it returned the token.
///
/// [`transmit_begin`]: Self::transmit_begin
Expand All @@ -191,7 +191,7 @@ impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONetRaw<H, T, QUEUE_SIZ
///
/// The caller can then call [`poll_receive`] with the returned token to
/// check whether the device has finished handling the request. Once it has,
/// the caller must call [`receive_complete`] with the same buffers before
/// the caller must call [`receive_complete`] with the same buffer before
/// reading the response.
///
/// # Safety
Expand Down Expand Up @@ -227,7 +227,7 @@ impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONetRaw<H, T, QUEUE_SIZ
///
/// # Safety
///
/// The same buffers must be passed in again as were passed to
/// The same buffer must be passed in again as were passed to
/// [`receive_begin`] when it returned the token.
///
/// [`receive_begin`]: Self::receive_begin
Expand Down Expand Up @@ -260,7 +260,7 @@ impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONetRaw<H, T, QUEUE_SIZ
/// completed.
pub fn send(&mut self, tx_buf: &[u8]) -> Result {
let header = VirtioNetHdr::default();
if tx_buf.len() == 0 {
if tx_buf.is_empty() {
// Special case sending an empty packet, to avoid adding an empty buffer to the
// virtqueue.
self.send_queue.add_notify_wait_pop(
Expand Down
24 changes: 6 additions & 18 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,27 +316,15 @@ impl<H: Hal, const SIZE: usize> VirtQueue<H, SIZE> {
unsafe { self.pop_used(token, inputs, outputs) }
}

/// Advise the device that notifications are needed.
/// Advise the device whether used buffer notifications are needed.
///
/// See Virtio v1.1 2.6.7 Used Buffer Notification Suppression
pub fn enable_dev_notify(&mut self) {
pub fn set_dev_notify(&mut self, enable: bool) {
let avail_ring_flags = if enable { 0x0000 } else { 0x0001 };
if !self.event_idx {
// Safe because self.avail points to a valid, aligned, initialised, dereferenceable, readable
// instance of AvailRing.
unsafe { (*self.avail.as_ptr()).flags = 0x0000 }
}
// Write barrier so that device can see change to available index after this method returns.
fence(Ordering::SeqCst);
}

/// Advise the device that notifications are not needed.
///
/// See Virtio v1.1 2.6.7 Used Buffer Notification Suppression
pub fn disable_dev_notify(&mut self) {
if !self.event_idx {
// Safe because self.avail points to a valid, aligned, initialised, dereferenceable, readable
// instance of AvailRing.
unsafe { (*self.avail.as_ptr()).flags = 0x0001 }
unsafe { (*self.avail.as_ptr()).flags = avail_ring_flags }
}
// Write barrier so that device can see change to available index after this method returns.
fence(Ordering::SeqCst);
Expand Down Expand Up @@ -1163,12 +1151,12 @@ mod tests {
// Check that the avail ring's flag is zero by default.
assert_eq!(unsafe { (*queue.avail.as_ptr()).flags }, 0x0);

queue.disable_dev_notify();
queue.set_dev_notify(false);

// Check that the avail ring's flag is 1 after `disable_dev_notify`.
assert_eq!(unsafe { (*queue.avail.as_ptr()).flags }, 0x1);

queue.enable_dev_notify();
queue.set_dev_notify(true);

// Check that the avail ring's flag is 0 after `enable_dev_notify`.
assert_eq!(unsafe { (*queue.avail.as_ptr()).flags }, 0x0);
Expand Down

0 comments on commit 8f288ea

Please sign in to comment.