Skip to content

Commit 479a1be

Browse files
committed
Raise interrupt for used descriptors on tx queue.
Add a unit test for this regression: #1436. Signed-off-by: Andrei Sandu <[email protected]>
1 parent f55da99 commit 479a1be

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
- The backtrace are printed on `panic`, no longer causing a seccomp fault.
99
- Fixed #1375 - Change logger options type from Value to Vec<LogOption> to
1010
prevent potential unwrap on None panics.
11+
- Raise interrupt for TX queue used descriptors - Github issue #1436
12+
- Fixed a bug that causes 100% cpu load when the net device rx is throttled
13+
by the ratelimiter - Github issue #1439
1114

1215
## [0.19.0]
1316

src/devices/src/virtio/net.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ impl NetEpollHandler {
397397
// trigger a process_rx() which checks if there are any new frames to be sent, starting
398398
// with the MMDS network stack.
399399
let mut process_rx_for_mmds = false;
400+
let mut raise_irq = false;
400401

401402
while let Some(head) = self.tx.queue.pop(&self.mem) {
402403
// If limiter.consume() fails it means there is no more TokenType::Ops
@@ -474,6 +475,11 @@ impl NetEpollHandler {
474475
}
475476

476477
self.tx.queue.add_used(&self.mem, head_index, 0);
478+
raise_irq = true;
479+
}
480+
481+
if raise_irq {
482+
self.signal_used_queue()?;
477483
}
478484

479485
// An incoming frame for the MMDS may trigger the transmission of a new message.
@@ -1599,7 +1605,7 @@ mod tests {
15991605
h.interrupt_evt.write(1).unwrap();
16001606
h.handle_event(RX_TAP_EVENT, EPOLLIN).unwrap();
16011607
assert!(h.rx.deferred_frame);
1602-
assert_eq!(h.interrupt_evt.read().unwrap(), 2);
1608+
assert_eq!(h.interrupt_evt.read().unwrap(), 3);
16031609
// The #cfg(test) enabled version of read_tap always returns 1234 bytes (or the len of
16041610
// the buffer, whichever is smaller).
16051611
assert_eq!(rxq.used.ring[0].get().len, 1234);
@@ -1750,7 +1756,7 @@ mod tests {
17501756
assert!(h.get_rx_rate_limiter().is_blocked());
17511757
assert!(h.rx.deferred_frame);
17521758
// assert that no operation actually completed (limiter blocked it)
1753-
assert_eq!(h.interrupt_evt.read().unwrap(), 1);
1759+
assert_eq!(h.interrupt_evt.read().unwrap(), 2);
17541760
// make sure the data is still queued for processing
17551761
assert_eq!(rxq.used.idx.get(), 0);
17561762
}
@@ -1853,7 +1859,7 @@ mod tests {
18531859
assert!(h.get_rx_rate_limiter().is_blocked());
18541860
assert!(h.rx.deferred_frame);
18551861
// assert that no operation actually completed (limiter blocked it)
1856-
assert_eq!(h.interrupt_evt.read().unwrap(), 1);
1862+
assert_eq!(h.interrupt_evt.read().unwrap(), 2);
18571863
// make sure the data is still queued for processing
18581864
assert_eq!(rxq.used.idx.get(), 0);
18591865

0 commit comments

Comments
 (0)