1
1
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
+ use std:: ops:: Deref ;
4
5
use std:: sync:: Arc ;
5
6
use std:: time:: Duration ;
6
7
@@ -24,8 +25,9 @@ use super::{
24
25
VIRTIO_BALLOON_S_SWAP_OUT ,
25
26
} ;
26
27
use crate :: devices:: virtio:: balloon:: BalloonError ;
28
+ use crate :: devices:: virtio:: device:: ActiveState ;
27
29
use crate :: devices:: virtio:: generated:: virtio_config:: VIRTIO_F_VERSION_1 ;
28
- use crate :: devices:: virtio:: transport:: mmio :: { IrqTrigger , IrqType } ;
30
+ use crate :: devices:: virtio:: transport:: { VirtioInterrupt , VirtioInterruptType } ;
29
31
use crate :: logger:: IncMetric ;
30
32
use crate :: utils:: u64_to_usize;
31
33
use crate :: vstate:: memory:: { Address , ByteValued , Bytes , GuestAddress , GuestMemoryMmap } ;
@@ -258,7 +260,7 @@ impl Balloon {
258
260
259
261
pub ( crate ) fn process_inflate ( & mut self ) -> Result < ( ) , BalloonError > {
260
262
// This is safe since we checked in the event handler that the device is activated.
261
- let ( mem, _ ) = self . device_state . active_state ( ) . unwrap ( ) ;
263
+ let mem = & self . device_state . active_state ( ) . unwrap ( ) . mem ;
262
264
METRICS . inflate_count . inc ( ) ;
263
265
264
266
let queue = & mut self . queues [ INFLATE_INDEX ] ;
@@ -339,7 +341,7 @@ impl Balloon {
339
341
}
340
342
341
343
if needs_interrupt {
342
- self . signal_used_queue ( ) ?;
344
+ self . signal_used_queue ( INFLATE_INDEX ) ?;
343
345
}
344
346
345
347
Ok ( ( ) )
@@ -357,15 +359,15 @@ impl Balloon {
357
359
}
358
360
359
361
if needs_interrupt {
360
- self . signal_used_queue ( )
362
+ self . signal_used_queue ( DEFLATE_INDEX )
361
363
} else {
362
364
Ok ( ( ) )
363
365
}
364
366
}
365
367
366
368
pub ( crate ) fn process_stats_queue ( & mut self ) -> Result < ( ) , BalloonError > {
367
369
// This is safe since we checked in the event handler that the device is activated.
368
- let ( mem, _ ) = self . device_state . active_state ( ) . unwrap ( ) ;
370
+ let mem = & self . device_state . active_state ( ) . unwrap ( ) . mem ;
369
371
METRICS . stats_updates_count . inc ( ) ;
370
372
371
373
while let Some ( head) = self . queues [ STATS_INDEX ] . pop ( ) {
@@ -401,9 +403,12 @@ impl Balloon {
401
403
Ok ( ( ) )
402
404
}
403
405
404
- pub ( crate ) fn signal_used_queue ( & self ) -> Result < ( ) , BalloonError > {
406
+ pub ( crate ) fn signal_used_queue ( & self , qidx : usize ) -> Result < ( ) , BalloonError > {
405
407
self . interrupt_trigger ( )
406
- . trigger_irq ( IrqType :: Vring )
408
+ . trigger ( VirtioInterruptType :: Queue (
409
+ qidx. try_into ( )
410
+ . unwrap_or_else ( |_| panic ! ( "balloon: invalid queue id: {qidx}" ) ) ,
411
+ ) )
407
412
. map_err ( |err| {
408
413
METRICS . event_fails . inc ( ) ;
409
414
BalloonError :: InterruptError ( err)
@@ -428,7 +433,7 @@ impl Balloon {
428
433
self . queues [ STATS_INDEX ]
429
434
. add_used ( index, 0 )
430
435
. map_err ( BalloonError :: Queue ) ?;
431
- self . signal_used_queue ( )
436
+ self . signal_used_queue ( STATS_INDEX )
432
437
} else {
433
438
error ! ( "Failed to update balloon stats, missing descriptor." ) ;
434
439
Ok ( ( ) )
@@ -440,7 +445,7 @@ impl Balloon {
440
445
if self . is_activated ( ) {
441
446
self . config_space . num_pages = mib_to_pages ( amount_mib) ?;
442
447
self . interrupt_trigger ( )
443
- . trigger_irq ( IrqType :: Config )
448
+ . trigger ( VirtioInterruptType :: Config )
444
449
. map_err ( BalloonError :: InterruptError )
445
450
} else {
446
451
Err ( BalloonError :: DeviceNotActive )
@@ -551,11 +556,12 @@ impl VirtioDevice for Balloon {
551
556
& self . queue_evts
552
557
}
553
558
554
- fn interrupt_trigger ( & self ) -> Arc < IrqTrigger > {
559
+ fn interrupt_trigger ( & self ) -> & dyn VirtioInterrupt {
555
560
self . device_state
556
561
. active_state ( )
557
562
. expect ( "Device is not activated" )
558
- . 1
563
+ . interrupt
564
+ . deref ( )
559
565
}
560
566
561
567
fn read_config ( & self , offset : u64 , data : & mut [ u8 ] ) {
@@ -585,14 +591,14 @@ impl VirtioDevice for Balloon {
585
591
fn activate (
586
592
& mut self ,
587
593
mem : GuestMemoryMmap ,
588
- interrupt : Arc < IrqTrigger > ,
594
+ interrupt : Arc < dyn VirtioInterrupt > ,
589
595
) -> Result < ( ) , ActivateError > {
590
596
for q in self . queues . iter_mut ( ) {
591
597
q. initialize ( & mem)
592
598
. map_err ( ActivateError :: QueueMemoryError ) ?;
593
599
}
594
600
595
- self . device_state = DeviceState :: Activated ( ( mem, interrupt) ) ;
601
+ self . device_state = DeviceState :: Activated ( ActiveState { mem, interrupt } ) ;
596
602
if self . activate_evt . write ( 1 ) . is_err ( ) {
597
603
METRICS . activate_fails . inc ( ) ;
598
604
self . device_state = DeviceState :: Inactive ;
@@ -621,7 +627,7 @@ pub(crate) mod tests {
621
627
check_request_completion, invoke_handler_for_queue_event, set_request,
622
628
} ;
623
629
use crate :: devices:: virtio:: queue:: { VIRTQ_DESC_F_NEXT , VIRTQ_DESC_F_WRITE } ;
624
- use crate :: devices:: virtio:: test_utils:: { VirtQueue , default_mem} ;
630
+ use crate :: devices:: virtio:: test_utils:: { VirtQueue , default_interrupt , default_mem} ;
625
631
use crate :: test_utils:: single_region_mem;
626
632
use crate :: vstate:: memory:: GuestAddress ;
627
633
@@ -798,11 +804,10 @@ pub(crate) mod tests {
798
804
fn test_invalid_request ( ) {
799
805
let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
800
806
let mem = default_mem ( ) ;
801
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
802
807
// Only initialize the inflate queue to demonstrate invalid request handling.
803
808
let infq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
804
809
balloon. set_queue ( INFLATE_INDEX , infq. create_queue ( ) ) ;
805
- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
810
+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
806
811
807
812
// Fill the second page with non-zero bytes.
808
813
for i in 0 ..0x1000 {
@@ -858,10 +863,9 @@ pub(crate) mod tests {
858
863
fn test_inflate ( ) {
859
864
let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
860
865
let mem = default_mem ( ) ;
861
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
862
866
let infq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
863
867
balloon. set_queue ( INFLATE_INDEX , infq. create_queue ( ) ) ;
864
- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
868
+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
865
869
866
870
// Fill the third page with non-zero bytes.
867
871
for i in 0 ..0x1000 {
@@ -929,10 +933,9 @@ pub(crate) mod tests {
929
933
fn test_deflate ( ) {
930
934
let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
931
935
let mem = default_mem ( ) ;
932
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
933
936
let defq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
934
937
balloon. set_queue ( DEFLATE_INDEX , defq. create_queue ( ) ) ;
935
- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
938
+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
936
939
937
940
let page_addr = 0x10 ;
938
941
@@ -978,10 +981,9 @@ pub(crate) mod tests {
978
981
fn test_stats ( ) {
979
982
let mut balloon = Balloon :: new ( 0 , true , 1 , false ) . unwrap ( ) ;
980
983
let mem = default_mem ( ) ;
981
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
982
984
let statsq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
983
985
balloon. set_queue ( STATS_INDEX , statsq. create_queue ( ) ) ;
984
- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
986
+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
985
987
986
988
let page_addr = 0x100 ;
987
989
@@ -1057,7 +1059,9 @@ pub(crate) mod tests {
1057
1059
assert!( balloon. stats_desc_index. is_some( ) ) ;
1058
1060
balloon. process_stats_timer_event( ) . unwrap( ) ;
1059
1061
assert!( balloon. stats_desc_index. is_none( ) ) ;
1060
- assert!( balloon. interrupt_trigger( ) . has_pending_irq( IrqType :: Vring ) ) ;
1062
+ assert!( balloon. interrupt_trigger( ) . has_pending_interrupt(
1063
+ VirtioInterruptType :: Queue ( STATS_INDEX . try_into( ) . unwrap( ) )
1064
+ ) ) ;
1061
1065
} ) ;
1062
1066
}
1063
1067
}
@@ -1066,23 +1070,21 @@ pub(crate) mod tests {
1066
1070
fn test_process_balloon_queues ( ) {
1067
1071
let mut balloon = Balloon :: new ( 0x10 , true , 0 , false ) . unwrap ( ) ;
1068
1072
let mem = default_mem ( ) ;
1069
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
1070
1073
let infq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
1071
1074
let defq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
1072
1075
1073
1076
balloon. set_queue ( INFLATE_INDEX , infq. create_queue ( ) ) ;
1074
1077
balloon. set_queue ( DEFLATE_INDEX , defq. create_queue ( ) ) ;
1075
1078
1076
- balloon. activate ( mem, interrupt ) . unwrap ( ) ;
1079
+ balloon. activate ( mem, default_interrupt ( ) ) . unwrap ( ) ;
1077
1080
balloon. process_virtio_queues ( )
1078
1081
}
1079
1082
1080
1083
#[ test]
1081
1084
fn test_update_stats_interval ( ) {
1082
1085
let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
1083
1086
let mem = default_mem ( ) ;
1084
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
1085
- balloon. activate ( mem, interrupt) . unwrap ( ) ;
1087
+ balloon. activate ( mem, default_interrupt ( ) ) . unwrap ( ) ;
1086
1088
assert_eq ! (
1087
1089
format!( "{:?}" , balloon. update_stats_polling_interval( 1 ) ) ,
1088
1090
"Err(StatisticsStateChange)"
@@ -1091,8 +1093,7 @@ pub(crate) mod tests {
1091
1093
1092
1094
let mut balloon = Balloon :: new ( 0 , true , 1 , false ) . unwrap ( ) ;
1093
1095
let mem = default_mem ( ) ;
1094
- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
1095
- balloon. activate ( mem, interrupt) . unwrap ( ) ;
1096
+ balloon. activate ( mem, default_interrupt ( ) ) . unwrap ( ) ;
1096
1097
assert_eq ! (
1097
1098
format!( "{:?}" , balloon. update_stats_polling_interval( 0 ) ) ,
1098
1099
"Err(StatisticsStateChange)"
@@ -1112,8 +1113,10 @@ pub(crate) mod tests {
1112
1113
fn test_num_pages ( ) {
1113
1114
let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
1114
1115
// Switch the state to active.
1115
- balloon. device_state =
1116
- DeviceState :: Activated ( ( single_region_mem ( 0x1 ) , Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ) ) ;
1116
+ balloon. device_state = DeviceState :: Activated ( ActiveState {
1117
+ mem : single_region_mem ( 0x1 ) ,
1118
+ interrupt : default_interrupt ( ) ,
1119
+ } ) ;
1117
1120
1118
1121
assert_eq ! ( balloon. num_pages( ) , 0 ) ;
1119
1122
assert_eq ! ( balloon. actual_pages( ) , 0 ) ;
0 commit comments