Skip to content

Commit 52bcaff

Browse files
committed
Update worker thread sender on x86
On x86, use the same sender as we would for macOS. Additionally, rather than using an EventFd to determine when the thread work is done, use a response sender/receiver like macOS. Signed-off-by: Jake Correnti <[email protected]>
1 parent f724291 commit 52bcaff

File tree

4 files changed

+71
-36
lines changed

4 files changed

+71
-36
lines changed

src/devices/src/legacy/ioapic.rs

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crossbeam_channel::unbounded;
12
use kvm_bindings::{
23
kvm_enable_cap, kvm_irq_routing, kvm_irq_routing_entry, kvm_irq_routing_entry__bindgen_ty_1,
34
kvm_irq_routing_msi, KVM_CAP_SPLIT_IRQCHIP, KVM_IRQ_ROUTING_MSI,
@@ -96,14 +97,13 @@ pub struct IoApic {
9697
version: u8,
9798
irq_eoi: [i32; IOAPIC_NUM_PINS],
9899
irq_routes: Vec<kvm_irq_routing_entry>,
99-
irq_sender: crossbeam_channel::Sender<(WorkerMessage, EventFd)>,
100-
event_fd: EventFd,
100+
irq_sender: crossbeam_channel::Sender<WorkerMessage>,
101101
}
102102

103103
impl IoApic {
104104
pub fn new(
105105
vm: &VmFd,
106-
_irq_sender: crossbeam_channel::Sender<(WorkerMessage, EventFd)>,
106+
_irq_sender: crossbeam_channel::Sender<WorkerMessage>,
107107
) -> Result<Self, Error> {
108108
let mut cap = kvm_enable_cap {
109109
cap: KVM_CAP_SPLIT_IRQCHIP,
@@ -121,7 +121,6 @@ impl IoApic {
121121
irq_eoi: [0; IOAPIC_NUM_PINS],
122122
irq_routes: Vec::with_capacity(IOAPIC_NUM_PINS),
123123
irq_sender: _irq_sender,
124-
event_fd: EventFd::new(libc::EFD_SEMAPHORE).unwrap(),
125124
};
126125

127126
(0..IOAPIC_NUM_PINS).for_each(|i| ioapic.add_msi_route(i));
@@ -175,14 +174,6 @@ impl IoApic {
175174
}
176175
}
177176

178-
fn send_irq_worker_message(&self, msg: WorkerMessage) {
179-
self.irq_sender
180-
.send((msg, self.event_fd.try_clone().unwrap()))
181-
.unwrap();
182-
183-
self.event_fd.read().unwrap();
184-
}
185-
186177
fn parse_entry(&self, entry: &RedirectionTableEntry) -> IoApicEntryInfo {
187178
let vector = (entry & IOAPIC_VECTOR_MASK) as u8;
188179
let dest_idx = ((entry >> IOAPIC_LVT_DEST_IDX_SHIFT) & 0xffff) as u16;
@@ -249,7 +240,16 @@ impl IoApic {
249240
}
250241
}
251242

252-
self.send_irq_worker_message(WorkerMessage::GsiRoute(self.irq_routes.clone()));
243+
let (response_sender, response_receiver) = unbounded();
244+
self.irq_sender
245+
.send(WorkerMessage::GsiRoute(
246+
response_sender.clone(),
247+
self.irq_routes.clone(),
248+
))
249+
.unwrap();
250+
if !response_receiver.recv().unwrap() {
251+
error!("unable to set GSI Routes for IO APIC");
252+
}
253253
}
254254

255255
fn service(&mut self) {
@@ -273,11 +273,49 @@ impl IoApic {
273273
continue;
274274
}
275275

276+
let (response_sender, response_receiver) = unbounded();
276277
if info.trig_mode as u64 == IOAPIC_TRIGGER_EDGE {
277-
self.send_irq_worker_message(WorkerMessage::IrqLine(i as u32, true));
278-
self.send_irq_worker_message(WorkerMessage::IrqLine(i as u32, false));
278+
self.irq_sender
279+
.send(WorkerMessage::IrqLine(
280+
response_sender.clone(),
281+
i as u32,
282+
true,
283+
))
284+
.unwrap();
285+
if !response_receiver.recv().unwrap() {
286+
error!(
287+
"unable to set IRQ LINE for IRQ {} with active set to {}",
288+
i, true
289+
);
290+
}
291+
292+
self.irq_sender
293+
.send(WorkerMessage::IrqLine(
294+
response_sender.clone(),
295+
i as u32,
296+
false,
297+
))
298+
.unwrap();
299+
if !response_receiver.recv().unwrap() {
300+
error!(
301+
"unable to set IRQ LINE for IRQ {} with active set to {}",
302+
i, false
303+
);
304+
}
279305
} else {
280-
self.send_irq_worker_message(WorkerMessage::IrqLine(i as u32, true));
306+
self.irq_sender
307+
.send(WorkerMessage::IrqLine(
308+
response_sender.clone(),
309+
i as u32,
310+
true,
311+
))
312+
.unwrap();
313+
if !response_receiver.recv().unwrap() {
314+
error!(
315+
"unable to set IRQ LINE for IRQ {} with active set to {}",
316+
i, true
317+
);
318+
}
281319
}
282320
}
283321
}

src/utils/src/worker_message.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#[derive(Debug)]
22
pub enum WorkerMessage {
33
#[cfg(target_arch = "x86_64")]
4-
GsiRoute(Vec<kvm_bindings::kvm_irq_routing_entry>),
4+
GsiRoute(
5+
crossbeam_channel::Sender<bool>,
6+
Vec<kvm_bindings::kvm_irq_routing_entry>,
7+
),
58
#[cfg(target_arch = "x86_64")]
6-
IrqLine(u32, bool),
9+
IrqLine(crossbeam_channel::Sender<bool>, u32, bool),
710
#[cfg(target_os = "macos")]
811
GpuAddMapping(crossbeam_channel::Sender<bool>, u64, u64, u64),
912
#[cfg(target_os = "macos")]

src/vmm/src/builder.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,7 @@ pub fn build_microvm(
512512
event_manager: &mut EventManager,
513513
_shutdown_efd: Option<EventFd>,
514514
#[cfg(feature = "tee")] pm_sender: (Sender<MemoryProperties>, EventFd),
515-
#[cfg(target_os = "macos")] _sender: Sender<WorkerMessage>,
516-
#[cfg(target_arch = "x86_64")] _sender: Sender<(WorkerMessage, EventFd)>,
515+
_sender: Sender<WorkerMessage>,
517516
) -> std::result::Result<Arc<Mutex<Vmm>>, StartMicrovmError> {
518517
let payload = choose_payload(vm_resources)?;
519518

src/vmm/src/worker.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
use std::io;
22
use std::sync::{Arc, Mutex};
33

4-
use utils::eventfd::EventFd;
54
use utils::worker_message::WorkerMessage;
65

76
use crossbeam_channel::Receiver;
87

98
pub fn start_worker_thread(
109
vmm: Arc<Mutex<super::Vmm>>,
11-
#[cfg(target_os = "macos")] receiver: Receiver<WorkerMessage>,
12-
#[cfg(not(target_os = "macos"))] receiver: Receiver<(WorkerMessage, EventFd)>,
10+
receiver: Receiver<WorkerMessage>,
1311
) -> io::Result<()> {
1412
std::thread::Builder::new()
1513
.name("vmm worker".into())
@@ -19,25 +17,21 @@ pub fn start_worker_thread(
1917
#[cfg(target_os = "macos")]
2018
Ok(message) => vmm.lock().unwrap().match_worker_message(message),
2119
#[cfg(target_os = "linux")]
22-
Ok((message, evt_fd)) => vmm.lock().unwrap().match_worker_message(message, evt_fd),
20+
Ok(message) => vmm.lock().unwrap().match_worker_message(message),
2321
}
2422
})?;
2523
Ok(())
2624
}
2725

2826
impl super::Vmm {
29-
fn match_worker_message(
30-
&self,
31-
msg: WorkerMessage,
32-
#[cfg(target_os = "linux")] evt_fd: EventFd,
33-
) {
27+
fn match_worker_message(&self, msg: WorkerMessage) {
3428
match msg {
3529
#[cfg(target_os = "macos")]
3630
WorkerMessage::GpuAddMapping(s, h, g, l) => self.add_mapping(s, h, g, l),
3731
#[cfg(target_os = "macos")]
3832
WorkerMessage::GpuRemoveMapping(s, g, l) => self.remove_mapping(s, g, l),
3933
#[cfg(target_arch = "x86_64")]
40-
WorkerMessage::GsiRoute(entries) => {
34+
WorkerMessage::GsiRoute(sender, entries) => {
4135
let mut irq_routing = utils::sized_vec::vec_with_array_field::<
4236
kvm_bindings::kvm_irq_routing,
4337
kvm_bindings::kvm_irq_routing_entry,
@@ -51,14 +45,15 @@ impl super::Vmm {
5145
entries_slice.copy_from_slice(&entries);
5246
}
5347

54-
self.vm.fd().set_gsi_routing(&irq_routing[0]).unwrap();
55-
56-
evt_fd.write(1).unwrap();
48+
sender
49+
.send(self.vm.fd().set_gsi_routing(&irq_routing[0]).is_ok())
50+
.unwrap();
5751
}
5852
#[cfg(target_arch = "x86_64")]
59-
WorkerMessage::IrqLine(irq, active) => {
60-
self.vm.fd().set_irq_line(irq, active).unwrap();
61-
evt_fd.write(1).unwrap();
53+
WorkerMessage::IrqLine(sender, irq, active) => {
54+
sender
55+
.send(self.vm.fd().set_irq_line(irq, active).is_ok())
56+
.unwrap();
6257
}
6358
}
6459
}

0 commit comments

Comments
 (0)