@@ -110,7 +110,7 @@ impl MsiVector {
110
110
/// MSI interrupts created for a VirtIO device
111
111
pub struct MsiVectorGroup {
112
112
vm : Arc < Vm > ,
113
- irq_routes : HashMap < u32 , MsiVector > ,
113
+ irq_routes : Vec < MsiVector > ,
114
114
}
115
115
116
116
impl MsiVectorGroup {
@@ -123,28 +123,25 @@ impl MsiVectorGroup {
123
123
}
124
124
125
125
impl < ' a > Persist < ' a > for MsiVectorGroup {
126
- type State = HashMap < u32 , u32 > ;
126
+ type State = Vec < u32 > ;
127
127
type ConstructorArgs = Arc < Vm > ;
128
128
type Error = InterruptError ;
129
129
130
130
fn save ( & self ) -> Self :: State {
131
131
// We don't save the "enabled" state of the MSI interrupt. PCI devices store the MSI-X
132
132
// configuration and make sure that the vector is enabled during the restore path if it was
133
133
// initially enabled
134
- self . irq_routes
135
- . iter ( )
136
- . map ( |( id, route) | ( * id, route. gsi ) )
137
- . collect ( )
134
+ self . irq_routes . iter ( ) . map ( |route| route. gsi ) . collect ( )
138
135
}
139
136
140
137
fn restore (
141
138
constructor_args : Self :: ConstructorArgs ,
142
139
state : & Self :: State ,
143
140
) -> std:: result:: Result < Self , Self :: Error > {
144
- let mut irq_routes = HashMap :: new ( ) ;
141
+ let mut irq_routes = Vec :: with_capacity ( state . len ( ) ) ;
145
142
146
- for ( id , gsi) in state {
147
- irq_routes. insert ( * id , MsiVector :: new ( * gsi, false ) ?) ;
143
+ for gsi in state {
144
+ irq_routes. push ( MsiVector :: new ( * gsi, false ) ?) ;
148
145
}
149
146
150
147
Ok ( MsiVectorGroup {
@@ -156,15 +153,15 @@ impl<'a> Persist<'a> for MsiVectorGroup {
156
153
157
154
impl InterruptSourceGroup for MsiVectorGroup {
158
155
fn enable ( & self ) -> vm_device:: interrupt:: Result < ( ) > {
159
- for route in self . irq_routes . values ( ) {
156
+ for route in & self . irq_routes {
160
157
route. enable ( & self . vm . common . fd ) ?;
161
158
}
162
159
163
160
Ok ( ( ) )
164
161
}
165
162
166
163
fn disable ( & self ) -> vm_device:: interrupt:: Result < ( ) > {
167
- for route in self . irq_routes . values ( ) {
164
+ for route in & self . irq_routes {
168
165
route. disable ( & self . vm . common . fd ) ?;
169
166
}
170
167
@@ -180,7 +177,9 @@ impl InterruptSourceGroup for MsiVectorGroup {
180
177
}
181
178
182
179
fn notifier ( & self , index : InterruptIndex ) -> Option < & EventFd > {
183
- self . irq_routes . get ( & index) . map ( |route| & route. event_fd )
180
+ self . irq_routes
181
+ . get ( index as usize )
182
+ . map ( |route| & route. event_fd )
184
183
}
185
184
186
185
fn update (
@@ -199,7 +198,7 @@ impl InterruptSourceGroup for MsiVectorGroup {
199
198
InterruptSourceConfig :: MsiIrq ( config) => config,
200
199
} ;
201
200
202
- if let Some ( route) = self . irq_routes . get ( & index) {
201
+ if let Some ( route) = self . irq_routes . get ( index as usize ) {
203
202
// When an interrupt is masked the GSI will not be passed to KVM through
204
203
// KVM_SET_GSI_ROUTING. So, call [`disable()`] to unregister the interrupt file
205
204
// descriptor before passing the interrupt routes to KVM
@@ -593,14 +592,13 @@ impl Vm {
593
592
/// Create a group of MSI-X interrupts
594
593
pub fn create_msix_group ( vm : Arc < Vm > , count : u16 ) -> Result < MsiVectorGroup , InterruptError > {
595
594
debug ! ( "Creating new MSI group with {count} vectors" ) ;
596
- let mut irq_routes = HashMap :: with_capacity ( count as usize ) ;
597
- for ( gsi, i ) in vm
595
+ let mut irq_routes = Vec :: with_capacity ( count as usize ) ;
596
+ for gsi in vm
598
597
. resource_allocator ( )
599
598
. allocate_gsi_msi ( count as u32 ) ?
600
599
. iter ( )
601
- . zip ( 0u32 ..)
602
600
{
603
- irq_routes. insert ( i , MsiVector :: new ( * gsi, false ) ?) ;
601
+ irq_routes. push ( MsiVector :: new ( * gsi, false ) ?) ;
604
602
}
605
603
606
604
Ok ( MsiVectorGroup { vm, irq_routes } )
@@ -821,21 +819,21 @@ pub(crate) mod tests {
821
819
let msix_group = create_msix_group ( & vm) ;
822
820
823
821
// Initially all vectors are disabled
824
- for route in msix_group. irq_routes . values ( ) {
822
+ for route in & msix_group. irq_routes {
825
823
assert ! ( !route. enabled. load( Ordering :: Acquire ) )
826
824
}
827
825
828
826
// Enable works
829
827
msix_group. enable ( ) . unwrap ( ) ;
830
- for route in msix_group. irq_routes . values ( ) {
828
+ for route in & msix_group. irq_routes {
831
829
assert ! ( route. enabled. load( Ordering :: Acquire ) ) ;
832
830
}
833
831
// Enabling an enabled group doesn't error out
834
832
msix_group. enable ( ) . unwrap ( ) ;
835
833
836
834
// Disable works
837
835
msix_group. disable ( ) . unwrap ( ) ;
838
- for route in msix_group. irq_routes . values ( ) {
836
+ for route in & msix_group. irq_routes {
839
837
assert ! ( !route. enabled. load( Ordering :: Acquire ) )
840
838
}
841
839
// Disabling a disabled group doesn't error out
@@ -921,7 +919,7 @@ pub(crate) mod tests {
921
919
}
922
920
923
921
// All vectors should be disabled
924
- for vector in msix_group. irq_routes . values ( ) {
922
+ for vector in & msix_group. irq_routes {
925
923
assert ! ( !vector. enabled. load( Ordering :: Acquire ) ) ;
926
924
}
927
925
@@ -1018,8 +1016,8 @@ pub(crate) mod tests {
1018
1016
// Even if an MSI group is enabled, we don't save it as such. During restoration, the PCI
1019
1017
// transport will make sure the correct config is set for the vectors and enable them
1020
1018
// accordingly.
1021
- for ( id, vector) in msix_group. irq_routes {
1022
- let new_vector = restored_group. irq_routes . get ( & id ) . unwrap ( ) ;
1019
+ for ( id, vector) in msix_group. irq_routes . iter ( ) . enumerate ( ) {
1020
+ let new_vector = & restored_group. irq_routes [ id ] ;
1023
1021
assert_eq ! ( vector. gsi, new_vector. gsi) ;
1024
1022
assert ! ( !new_vector. enabled. load( Ordering :: Acquire ) ) ;
1025
1023
}
0 commit comments