Skip to content

Commit 4f04aff

Browse files
committed
refactor: only notify rx if there are processed packets
There is no point of notifing guest if there are no fully processed packets. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent d08a0ed commit 4f04aff

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

src/vmm/src/devices/virtio/net/device.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -521,14 +521,17 @@ impl Net {
521521
self.read_tap().map_err(NetError::IO)
522522
}
523523

524-
fn process_rx(&mut self) -> Result<(), DeviceError> {
524+
fn process_rx(&mut self) -> Result<bool, DeviceError> {
525+
let mut signal_queue = false;
525526
// Read as many frames as possible.
526527
loop {
527528
match self.read_from_mmds_or_tap() {
528529
Ok(count) => {
529530
self.rx_bytes_read = count;
530531
self.metrics.rx_count.inc();
531-
if !self.rate_limited_rx_single_frame() {
532+
if self.rate_limited_rx_single_frame() {
533+
signal_queue = true;
534+
} else {
532535
self.rx_deferred_frame = true;
533536
break;
534537
}
@@ -552,9 +555,11 @@ impl Net {
552555
}
553556
}
554557

555-
// At this point we processed as many Rx frames as possible.
556-
// We have to wake the guest if at least one descriptor chain has been used.
557-
self.signal_used_queue(NetQueue::Rx)
558+
// We only notify guest if there is at least one packet processed successfully.
559+
if signal_queue {
560+
self.signal_used_queue(NetQueue::Rx)?;
561+
}
562+
Ok(signal_queue)
558563
}
559564

560565
// Process the deferred frame first, then continue reading from tap.
@@ -563,10 +568,12 @@ impl Net {
563568
self.rx_deferred_frame = false;
564569
// process_rx() was interrupted possibly before consuming all
565570
// packets in the tap; try continuing now.
566-
return self.process_rx();
571+
// we only signal queue if process_rx() did not already.
572+
if !self.process_rx()? {
573+
self.signal_used_queue(NetQueue::Rx)?;
574+
}
567575
}
568-
569-
self.signal_used_queue(NetQueue::Rx)
576+
Ok(())
570577
}
571578

572579
fn resume_rx(&mut self) -> Result<(), DeviceError> {
@@ -651,10 +658,9 @@ impl Net {
651658

652659
// An incoming frame for the MMDS may trigger the transmission of a new message.
653660
if process_rx_for_mmds {
654-
self.process_rx()
655-
} else {
656-
Ok(())
661+
self.process_rx()?;
657662
}
663+
Ok(())
658664
}
659665

660666
/// Builds the offload features we will setup on the TAP device based on the features that the
@@ -759,15 +765,14 @@ impl Net {
759765
return;
760766
}
761767

762-
if self.rx_deferred_frame
763768
// Process a deferred frame first if available. Don't read from tap again
764769
// until we manage to receive this deferred frame.
765-
{
766-
self.handle_deferred_frame()
767-
.unwrap_or_else(|err| report_net_event_fail(&self.metrics, err));
768-
} else {
769-
self.process_rx()
770-
.unwrap_or_else(|err| report_net_event_fail(&self.metrics, err));
770+
if self.rx_deferred_frame {
771+
if let Err(err) = self.handle_deferred_frame() {
772+
report_net_event_fail(&self.metrics, err);
773+
}
774+
} else if let Err(err) = self.process_rx() {
775+
report_net_event_fail(&self.metrics, err);
771776
}
772777
}
773778

src/vmm/src/devices/virtio/net/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ pub mod test {
501501
assert!(self.net().rx_deferred_frame);
502502
// Check that the descriptor chain has been discarded.
503503
assert_eq!(self.rxq.used.idx.get(), used_idx + 1);
504-
assert!(&self.net().irq_trigger.has_pending_irq(IrqType::Vring));
504+
assert!(!self.net().irq_trigger.has_pending_irq(IrqType::Vring));
505505

506506
frame
507507
}

0 commit comments

Comments
 (0)