Skip to content

Commit 009ec85

Browse files
committed
net: fix rx queue freeze
Under heavy ingress traffic we might end up in a situation where the tap device is full, but the rx.deferred_frame flag is not set. Beeing in this state the firecracker RX queue becomes effectively blocked. The tap won't issue any new event because of the EPOLLET flag, while any rate limiter or RX queue event won't do any processing because the rx.deferred_frame flag is not set. We need to make sure we set the rx.deferred_frame flag on all the paths that leave unprocessed frames in the tap. Signed-off-by: Serban Iorga <[email protected]> Signed-off-by: Ioana Chirca <[email protected]>
1 parent 043254f commit 009ec85

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,12 @@ impl Net {
625625
DeviceState::Inactive => unreachable!(),
626626
};
627627
METRICS.net.rx_tap_event_count.inc();
628-
if self.queues[RX_INDEX].is_empty(mem) {
628+
629+
// While there are no available RX queue buffers and there's a deferred_frame
630+
// don't process any more incoming. Otherwise start processing a frame. In the
631+
// process the deferred_frame flag will be set in order to avoid freezing the
632+
// RX queue.
633+
if self.queues[RX_INDEX].is_empty(mem) && self.rx_deferred_frame {
629634
METRICS.net.no_rx_avail_buffer.inc();
630635
return;
631636
}
@@ -1699,7 +1704,8 @@ pub mod tests {
16991704
th.activate_net();
17001705
th.net().mocks.set_read_tap(ReadTapMock::Failure);
17011706

1702-
// The RX queue is empty.
1707+
// The RX queue is empty and rx_deffered_frame is set.
1708+
th.net().rx_deferred_frame = true;
17031709
check_metric_after_block!(
17041710
&METRICS.net.no_rx_avail_buffer,
17051711
1,

0 commit comments

Comments
 (0)