Skip to content

Commit c637afa

Browse files
acatangiuiulianbarbu
authored andcommitted
devices: net: activate through an activation event
Postpone net external events registration to device activation time. This makes the net device unaware of external events prior to its activation. During creation register a dedicated activation event which will notify the device when it's time to register the other external events sources. This activation event is unregistered after successful device activation. Signed-off-by: Adrian Catangiu <acatan@amazon.com>
1 parent 4468055 commit c637afa

File tree

4 files changed

+264
-77
lines changed

4 files changed

+264
-77
lines changed

src/devices/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ pub enum Error {
4747
PayloadExpected,
4848
IoError(io::Error),
4949
NoAvailBuffers,
50+
SpuriousEvent,
5051
}

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

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use crate::virtio::net::Error;
99
use crate::virtio::net::Result;
1010
use crate::virtio::net::{MAX_BUFFER_SIZE, QUEUE_SIZE, QUEUE_SIZES, RX_INDEX, TX_INDEX};
11-
use crate::virtio::{ActivateResult, Queue, VirtioDevice, TYPE_NET, VIRTIO_MMIO_INT_VRING};
11+
use crate::virtio::{
12+
ActivateResult, DeviceState, Queue, VirtioDevice, TYPE_NET, VIRTIO_MMIO_INT_VRING,
13+
};
1214
use crate::{report_net_event_fail, Error as DeviceError};
1315
use dumbo::ns::MmdsNetworkStack;
1416
use dumbo::{EthernetFrame, MacAddr, MAC_ADDR_LEN};
@@ -59,8 +61,6 @@ pub struct Net {
5961
avail_features: u64,
6062
acked_features: u64,
6163

62-
mem: GuestMemoryMmap,
63-
6464
pub(crate) queues: Vec<Queue>,
6565
pub(crate) queue_evts: Vec<EventFd>,
6666

@@ -82,7 +82,8 @@ pub struct Net {
8282
config_space: Vec<u8>,
8383
guest_mac: Option<MacAddr>,
8484

85-
device_activated: bool,
85+
pub(crate) device_state: DeviceState,
86+
pub(crate) activate_evt: EventFd,
8687

8788
mmds_ns: Option<MmdsNetworkStack>,
8889

@@ -95,7 +96,6 @@ impl Net {
9596
pub fn new_with_tap(
9697
tap: Tap,
9798
guest_mac: Option<&MacAddr>,
98-
mem: GuestMemoryMmap,
9999
rx_rate_limiter: RateLimiter,
100100
tx_rate_limiter: RateLimiter,
101101
allow_mmds_requests: bool,
@@ -148,7 +148,6 @@ impl Net {
148148
tap,
149149
avail_features,
150150
acked_features: 0u64,
151-
mem,
152151
queues,
153152
queue_evts,
154153
rx_rate_limiter,
@@ -161,7 +160,8 @@ impl Net {
161160
tx_iovec: Vec::with_capacity(QUEUE_SIZE as usize),
162161
interrupt_status: Arc::new(AtomicUsize::new(0)),
163162
interrupt_evt: EventFd::new(libc::EFD_NONBLOCK).map_err(Error::EventFd)?,
164-
device_activated: false,
163+
device_state: DeviceState::Inactive,
164+
activate_evt: EventFd::new(libc::EFD_NONBLOCK).map_err(Error::EventFd)?,
165165
config_space,
166166
guest_mac,
167167
mmds_ns,
@@ -219,8 +219,13 @@ impl Net {
219219
// if a buffer was used, and false if the frame must be deferred until a buffer
220220
// is made available by the driver.
221221
fn rx_single_frame(&mut self) -> bool {
222+
let mem = match self.device_state {
223+
DeviceState::Activated(ref mem) => mem,
224+
// This should never happen, it's been already validated in the event handler.
225+
DeviceState::Inactive => unreachable!(),
226+
};
222227
let rx_queue = &mut self.queues[RX_INDEX];
223-
let mut next_desc = rx_queue.pop(&self.mem);
228+
let mut next_desc = rx_queue.pop(mem);
224229
if next_desc.is_none() {
225230
METRICS.net.no_rx_avail_buffer.inc();
226231
return false;
@@ -240,7 +245,7 @@ impl Net {
240245

241246
let limit = cmp::min(write_count + desc.len as usize, self.rx_bytes_read);
242247
let source_slice = &self.rx_frame_buf[write_count..limit];
243-
let write_result = self.mem.write_slice(source_slice, desc.addr);
248+
let write_result = mem.write_slice(source_slice, desc.addr);
244249

245250
match write_result {
246251
Ok(()) => {
@@ -270,7 +275,7 @@ impl Net {
270275
}
271276
}
272277

273-
rx_queue.add_used(&self.mem, head_index, write_count as u32);
278+
rx_queue.add_used(mem, head_index, write_count as u32);
274279

275280
// Mark that we have at least one pending packet and we need to interrupt the guest.
276281
self.rx_deferred_irqs = true;
@@ -406,6 +411,12 @@ impl Net {
406411
}
407412

408413
fn process_tx(&mut self) -> result::Result<(), DeviceError> {
414+
let mem = match self.device_state {
415+
DeviceState::Activated(ref mem) => mem,
416+
// This should never happen, it's been already validated in the event handler.
417+
DeviceState::Inactive => unreachable!(),
418+
};
419+
409420
// The MMDS network stack works like a state machine, based on synchronous calls, and
410421
// without being added to any event loop. If any frame is accepted by the MMDS, we also
411422
// trigger a process_rx() which checks if there are any new frames to be sent, starting
@@ -414,7 +425,7 @@ impl Net {
414425
let mut raise_irq = false;
415426
let tx_queue = &mut self.queues[TX_INDEX];
416427

417-
while let Some(head) = tx_queue.pop(&self.mem) {
428+
while let Some(head) = tx_queue.pop(mem) {
418429
// If limiter.consume() fails it means there is no more TokenType::Ops
419430
// budget and rate limiting is in effect.
420431
if !self.tx_rate_limiter.consume(1, TokenType::Ops) {
@@ -459,7 +470,7 @@ impl Net {
459470
for (desc_addr, desc_len) in self.tx_iovec.drain(..) {
460471
let limit = cmp::min((read_count + desc_len) as usize, self.tx_frame_buf.len());
461472

462-
let read_result = self.mem.read_slice(
473+
let read_result = mem.read_slice(
463474
&mut self.tx_frame_buf[read_count..limit as usize],
464475
desc_addr,
465476
);
@@ -491,7 +502,7 @@ impl Net {
491502
process_rx_for_mmds = true;
492503
}
493504

494-
tx_queue.add_used(&self.mem, head_index, 0);
505+
tx_queue.add_used(mem, head_index, 0);
495506
raise_irq = true;
496507
}
497508

@@ -542,8 +553,13 @@ impl Net {
542553
}
543554

544555
pub fn process_tap_rx_event(&mut self) {
556+
let mem = match self.device_state {
557+
DeviceState::Activated(ref mem) => mem,
558+
// This should never happen, it's been already validated in the event handler.
559+
DeviceState::Inactive => unreachable!(),
560+
};
545561
METRICS.net.rx_tap_event_count.inc();
546-
if self.queues[RX_INDEX].is_empty(&self.mem) {
562+
if self.queues[RX_INDEX].is_empty(mem) {
547563
METRICS.net.no_rx_avail_buffer.inc();
548564
return;
549565
}
@@ -676,20 +692,28 @@ impl VirtioDevice for Net {
676692
}
677693

678694
fn is_activated(&self) -> bool {
679-
self.device_activated
695+
match self.device_state {
696+
DeviceState::Inactive => false,
697+
DeviceState::Activated(_) => true,
698+
}
680699
}
681700

682-
fn activate(&mut self, _: GuestMemoryMmap) -> ActivateResult {
683-
self.device_activated = true;
701+
fn activate(&mut self, mem: GuestMemoryMmap) -> ActivateResult {
702+
if self.activate_evt.write(1).is_err() {
703+
error!("Net: Cannot write to activate_evt");
704+
return Err(super::super::ActivateError::BadActivate);
705+
}
706+
self.device_state = DeviceState::Activated(mem);
684707
Ok(())
685708
}
686709
}
687710

688711
#[cfg(test)]
689-
mod tests {
712+
pub(crate) mod tests {
690713
use std::net::Ipv4Addr;
691714
use std::os::unix::io::AsRawFd;
692715
use std::sync::atomic::{AtomicUsize, Ordering};
716+
use std::sync::Mutex;
693717
use std::time::Duration;
694718
use std::{io, mem, thread};
695719

@@ -741,7 +765,7 @@ mod tests {
741765
}
742766
}
743767

744-
trait TestUtil {
768+
pub(crate) trait TestUtil {
745769
fn default_net(test_mutators: TestMutators) -> Net;
746770
fn default_guest_mac() -> MacAddr;
747771
fn default_guest_memory() -> GuestMemoryMmap;
@@ -762,7 +786,6 @@ mod tests {
762786
let mut net = Net::new_with_tap(
763787
tap,
764788
Some(&guest_mac),
765-
Net::default_guest_memory(),
766789
RateLimiter::default(),
767790
RateLimiter::default(),
768791
true,
@@ -812,7 +835,6 @@ mod tests {
812835
self.queues.clear();
813836
self.queues.push(rxq);
814837
self.queues.push(txq);
815-
self.activate(self.mem.clone()).unwrap();
816838
}
817839
}
818840

@@ -931,12 +953,13 @@ mod tests {
931953
}
932954

933955
#[test]
934-
fn test_event_handling() {
956+
fn test_event_processing() {
935957
let mut event_manager = EventManager::new().unwrap();
936958
let mut net = Net::default_net(TestMutators::default());
937-
let mem_clone = net.mem.clone();
938-
let (rxq, txq) = Net::virtqueues(&mem_clone);
959+
let mem = Net::default_guest_memory();
960+
let (rxq, txq) = Net::virtqueues(&mem);
939961
net.assign_queues(rxq.create_queue(), txq.create_queue());
962+
net.activate(mem.clone()).unwrap();
940963

941964
let daddr = 0x2000;
942965
assert!(daddr > txq.end().0);
@@ -1213,9 +1236,10 @@ mod tests {
12131236
fn test_process_error_cases() {
12141237
let mut event_manager = EventManager::new().unwrap();
12151238
let mut net = Net::default_net(TestMutators::default());
1216-
let mem_clone = net.mem.clone();
1217-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1239+
let mem = Net::default_guest_memory();
1240+
let (rxq, txq) = Net::virtqueues(&mem);
12181241
net.assign_queues(rxq.create_queue(), txq.create_queue());
1242+
net.activate(mem.clone()).unwrap();
12191243

12201244
// RX rate limiter events should error since the limiter is not blocked.
12211245
// Validate that the event failed and failure was properly accounted for.
@@ -1242,15 +1266,27 @@ mod tests {
12421266
fn test_invalid_event() {
12431267
let mut event_manager = EventManager::new().unwrap();
12441268
let mut net = Net::default_net(TestMutators::default());
1245-
let mem_clone = net.mem.clone();
1246-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1269+
1270+
let mem = Net::default_guest_memory();
1271+
let (rxq, txq) = Net::virtqueues(&mem);
12471272
net.assign_queues(rxq.create_queue(), txq.create_queue());
1273+
net.activate(mem.clone()).unwrap();
1274+
1275+
let net = Arc::new(Mutex::new(net));
1276+
event_manager.add_subscriber(net.clone()).unwrap();
1277+
1278+
// Process the activate event.
1279+
let ev_count = event_manager.run_with_timeout(50).unwrap();
1280+
assert_eq!(ev_count, 1);
12481281

1282+
// Inject invalid event.
12491283
let invalid_event = EpollEvent::new(EventSet::IN, 1000);
12501284
check_metric_after_block!(
12511285
&METRICS.net.event_fails,
12521286
1,
1253-
net.process(&invalid_event, &mut event_manager)
1287+
net.lock()
1288+
.unwrap()
1289+
.process(&invalid_event, &mut event_manager)
12541290
);
12551291
}
12561292

@@ -1265,9 +1301,10 @@ mod tests {
12651301
};
12661302

12671303
let mut net = Net::default_net(test_mutators);
1268-
let mem_clone = net.mem.clone();
1269-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1304+
let mem = Net::default_guest_memory();
1305+
let (rxq, txq) = Net::virtqueues(&mem);
12701306
net.assign_queues(rxq.create_queue(), txq.create_queue());
1307+
net.activate(mem.clone()).unwrap();
12711308

12721309
// The RX queue is empty.
12731310
let tap_event = EpollEvent::new(EventSet::IN, net.tap.as_raw_fd() as u64);
@@ -1290,9 +1327,10 @@ mod tests {
12901327
fn test_rx_rate_limiter_handling() {
12911328
let mut event_manager = EventManager::new().unwrap();
12921329
let mut net = Net::default_net(TestMutators::default());
1293-
let mem_clone = net.mem.clone();
1294-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1330+
let mem = Net::default_guest_memory();
1331+
let (rxq, txq) = Net::virtqueues(&mem);
12951332
net.assign_queues(rxq.create_queue(), txq.create_queue());
1333+
net.activate(mem.clone()).unwrap();
12961334

12971335
net.rx_rate_limiter = RateLimiter::new(0, None, 0, 0, None, 0).unwrap();
12981336
let rate_limiter_event =
@@ -1308,9 +1346,10 @@ mod tests {
13081346
fn test_tx_rate_limiter_handling() {
13091347
let mut event_manager = EventManager::new().unwrap();
13101348
let mut net = Net::default_net(TestMutators::default());
1311-
let mem_clone = net.mem.clone();
1312-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1349+
let mem = Net::default_guest_memory();
1350+
let (rxq, txq) = Net::virtqueues(&mem);
13131351
net.assign_queues(rxq.create_queue(), txq.create_queue());
1352+
net.activate(mem.clone()).unwrap();
13141353

13151354
net.tx_rate_limiter = RateLimiter::new(0, None, 0, 0, None, 0).unwrap();
13161355
let rate_limiter_event =
@@ -1327,9 +1366,10 @@ mod tests {
13271366
fn test_bandwidth_rate_limiter() {
13281367
let mut event_manager = EventManager::new().unwrap();
13291368
let mut net = Net::default_net(TestMutators::default());
1330-
let mem_clone = net.mem.clone();
1331-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1369+
let mem = Net::default_guest_memory();
1370+
let (rxq, txq) = Net::virtqueues(&mem);
13321371
net.assign_queues(rxq.create_queue(), txq.create_queue());
1372+
net.activate(mem.clone()).unwrap();
13331373

13341374
let daddr = 0x2000;
13351375
assert!(daddr > txq.end().0);
@@ -1445,9 +1485,10 @@ mod tests {
14451485
fn test_ops_rate_limiter() {
14461486
let mut event_manager = EventManager::new().unwrap();
14471487
let mut net = Net::default_net(TestMutators::default());
1448-
let mem_clone = net.mem.clone();
1449-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1488+
let mem = Net::default_guest_memory();
1489+
let (rxq, txq) = Net::virtqueues(&mem);
14501490
net.assign_queues(rxq.create_queue(), txq.create_queue());
1491+
net.activate(mem.clone()).unwrap();
14511492

14521493
let daddr = 0x2000;
14531494
assert!(daddr > txq.end().0);
@@ -1564,9 +1605,10 @@ mod tests {
15641605
#[test]
15651606
fn test_patch_rate_limiters() {
15661607
let mut net = Net::default_net(TestMutators::default());
1567-
let mem_clone = net.mem.clone();
1568-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1608+
let mem = Net::default_guest_memory();
1609+
let (rxq, txq) = Net::virtqueues(&mem);
15691610
net.assign_queues(rxq.create_queue(), txq.create_queue());
1611+
net.activate(mem.clone()).unwrap();
15701612

15711613
net.rx_rate_limiter = RateLimiter::new(10, None, 10, 2, None, 2).unwrap();
15721614
net.tx_rate_limiter = RateLimiter::new(10, None, 10, 2, None, 2).unwrap();
@@ -1600,9 +1642,10 @@ mod tests {
16001642
// Regression test for https://github.com/firecracker-microvm/firecracker/issues/1436 .
16011643
let mut event_manager = EventManager::new().unwrap();
16021644
let mut net = Net::default_net(TestMutators::default());
1603-
let mem_clone = net.mem.clone();
1604-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1645+
let mem = Net::default_guest_memory();
1646+
let (rxq, txq) = Net::virtqueues(&mem);
16051647
net.assign_queues(rxq.create_queue(), txq.create_queue());
1648+
net.activate(mem.clone()).unwrap();
16061649

16071650
let daddr = 0x2000;
16081651
assert!(daddr > txq.end().0);
@@ -1626,9 +1669,10 @@ mod tests {
16261669
#[test]
16271670
fn test_virtio_device() {
16281671
let mut net = Net::default_net(TestMutators::default());
1629-
let mem_clone = net.mem.clone();
1630-
let (rxq, txq) = Net::virtqueues(&mem_clone);
1672+
let mem = Net::default_guest_memory();
1673+
let (rxq, txq) = Net::virtqueues(&mem);
16311674
net.assign_queues(rxq.create_queue(), txq.create_queue());
1675+
net.activate(mem.clone()).unwrap();
16321676

16331677
// Test queues count (TX and RX).
16341678
let queues = net.queues();

0 commit comments

Comments
 (0)