Skip to content

Commit 6e42550

Browse files
committed
vm-allocator: free GSIs when they are no longer used
These changes free GSIs when they are no longer used. That way we won't exhaust the available GSIs anymore when attaching and detaching devices. On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
1 parent ece022a commit 6e42550

3 files changed

Lines changed: 22 additions & 3 deletions

File tree

vm-allocator/src/gsi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ impl GsiAllocator {
197197
self.gsis.alloc()
198198
}
199199

200+
/// Frees a GSI
201+
pub fn free_gsi(&mut self, vector: u32) -> Result<(), InterruptAllocError> {
202+
self.gsis.free(vector)
203+
}
204+
200205
#[cfg(target_arch = "x86_64")]
201206
/// Allocate an IRQ
202207
pub fn allocate_irq(&mut self) -> Result<u32, InterruptAllocError> {

vm-allocator/src/system.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ impl SystemAllocator {
9191
self.gsi_allocator.allocate_gsi()
9292
}
9393

94+
/// Frees the given GSI.
95+
pub fn free_gsi(&mut self, vector: u32) -> Result<(), InterruptAllocError> {
96+
self.gsi_allocator.free_gsi(vector)
97+
}
98+
9499
/// Reserves a section of `size` bytes of IO address space.
95100
pub fn allocate_io_addresses(
96101
&mut self,

vmm/src/interrupt.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,23 @@ struct InterruptRoute {
2424
gsi: u32,
2525
irq_fd: EventFd,
2626
registered: AtomicBool,
27+
allocator: Arc<Mutex<SystemAllocator>>,
2728
}
2829

2930
impl InterruptRoute {
30-
pub fn new(allocator: &mut SystemAllocator) -> Result<Self> {
31+
pub fn new(allocator: Arc<Mutex<SystemAllocator>>) -> Result<Self> {
3132
let irq_fd = EventFd::new(libc::EFD_NONBLOCK)?;
3233
let gsi = allocator
34+
.lock()
35+
.unwrap()
3336
.allocate_gsi()
3437
.map_err(|e| io::Error::other(format!("Failed allocating new GSI: {e}")))?;
3538

3639
Ok(InterruptRoute {
3740
gsi,
3841
irq_fd,
3942
registered: AtomicBool::new(false),
43+
allocator,
4044
})
4145
}
4246

@@ -77,6 +81,12 @@ impl InterruptRoute {
7781
}
7882
}
7983

84+
impl Drop for InterruptRoute {
85+
fn drop(&mut self) {
86+
let _ = self.allocator.lock().unwrap().free_gsi(self.gsi);
87+
}
88+
}
89+
8090
pub struct RoutingEntry {
8191
route: IrqRoutingEntry,
8292
masked: bool,
@@ -292,11 +302,10 @@ impl InterruptManager for MsiInterruptManager {
292302
type GroupConfig = MsiIrqGroupConfig;
293303

294304
fn create_group(&self, config: Self::GroupConfig) -> Result<Arc<dyn InterruptSourceGroup>> {
295-
let mut allocator = self.allocator.lock().unwrap();
296305
let mut irq_routes: HashMap<InterruptIndex, InterruptRoute> =
297306
HashMap::with_capacity(config.count as usize);
298307
for i in config.base..config.base + config.count {
299-
irq_routes.insert(i, InterruptRoute::new(&mut allocator)?);
308+
irq_routes.insert(i, InterruptRoute::new(self.allocator.clone())?);
300309
}
301310

302311
Ok(Arc::new(MsiInterruptGroup::new(

0 commit comments

Comments
 (0)