Skip to content

Commit d5d31b4

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 5e14760 commit d5d31b4

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
@@ -522,14 +522,17 @@ impl Net {
522522
self.read_tap().map_err(NetError::IO)
523523
}
524524

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

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

561566
// Process the deferred frame first, then continue reading from tap.
@@ -564,10 +569,12 @@ impl Net {
564569
self.rx_deferred_frame = false;
565570
// process_rx() was interrupted possibly before consuming all
566571
// packets in the tap; try continuing now.
567-
return self.process_rx();
572+
// we only signal queue if process_rx() did not already.
573+
if !self.process_rx()? {
574+
self.signal_used_queue(NetQueue::Rx)?;
575+
}
568576
}
569-
570-
self.signal_used_queue(NetQueue::Rx)
577+
Ok(())
571578
}
572579

573580
fn resume_rx(&mut self) -> Result<(), DeviceError> {
@@ -652,10 +659,9 @@ impl Net {
652659

653660
// An incoming frame for the MMDS may trigger the transmission of a new message.
654661
if process_rx_for_mmds {
655-
self.process_rx()
656-
} else {
657-
Ok(())
662+
self.process_rx()?;
658663
}
664+
Ok(())
659665
}
660666

661667
/// Updates the parameters for the rate limiters
@@ -720,15 +726,14 @@ impl Net {
720726
return;
721727
}
722728

723-
if self.rx_deferred_frame
724729
// Process a deferred frame first if available. Don't read from tap again
725730
// until we manage to receive this deferred frame.
726-
{
727-
self.handle_deferred_frame()
728-
.unwrap_or_else(|err| report_net_event_fail(&self.metrics, err));
729-
} else {
730-
self.process_rx()
731-
.unwrap_or_else(|err| report_net_event_fail(&self.metrics, err));
731+
if self.rx_deferred_frame {
732+
if let Err(err) = self.handle_deferred_frame() {
733+
report_net_event_fail(&self.metrics, err);
734+
}
735+
} else if let Err(err) = self.process_rx() {
736+
report_net_event_fail(&self.metrics, err);
732737
}
733738
}
734739

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)