11// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
33
4+ use std:: ops:: Deref ;
45use std:: sync:: Arc ;
56use std:: time:: Duration ;
67
@@ -24,8 +25,9 @@ use super::{
2425 VIRTIO_BALLOON_S_SWAP_OUT ,
2526} ;
2627use crate :: devices:: virtio:: balloon:: BalloonError ;
28+ use crate :: devices:: virtio:: device:: ActiveState ;
2729use 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 } ;
2931use crate :: logger:: IncMetric ;
3032use crate :: utils:: u64_to_usize;
3133use crate :: vstate:: memory:: { Address , ByteValued , Bytes , GuestAddress , GuestMemoryMmap } ;
@@ -258,7 +260,7 @@ impl Balloon {
258260
259261 pub ( crate ) fn process_inflate ( & mut self ) -> Result < ( ) , BalloonError > {
260262 // 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 ;
262264 METRICS . inflate_count . inc ( ) ;
263265
264266 let queue = & mut self . queues [ INFLATE_INDEX ] ;
@@ -339,7 +341,7 @@ impl Balloon {
339341 }
340342
341343 if needs_interrupt {
342- self . signal_used_queue ( ) ?;
344+ self . signal_used_queue ( INFLATE_INDEX ) ?;
343345 }
344346
345347 Ok ( ( ) )
@@ -357,15 +359,15 @@ impl Balloon {
357359 }
358360
359361 if needs_interrupt {
360- self . signal_used_queue ( )
362+ self . signal_used_queue ( DEFLATE_INDEX )
361363 } else {
362364 Ok ( ( ) )
363365 }
364366 }
365367
366368 pub ( crate ) fn process_stats_queue ( & mut self ) -> Result < ( ) , BalloonError > {
367369 // 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 ;
369371 METRICS . stats_updates_count . inc ( ) ;
370372
371373 while let Some ( head) = self . queues [ STATS_INDEX ] . pop ( ) {
@@ -401,9 +403,12 @@ impl Balloon {
401403 Ok ( ( ) )
402404 }
403405
404- pub ( crate ) fn signal_used_queue ( & self ) -> Result < ( ) , BalloonError > {
406+ pub ( crate ) fn signal_used_queue ( & self , qidx : usize ) -> Result < ( ) , BalloonError > {
405407 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+ ) )
407412 . map_err ( |err| {
408413 METRICS . event_fails . inc ( ) ;
409414 BalloonError :: InterruptError ( err)
@@ -428,7 +433,7 @@ impl Balloon {
428433 self . queues [ STATS_INDEX ]
429434 . add_used ( index, 0 )
430435 . map_err ( BalloonError :: Queue ) ?;
431- self . signal_used_queue ( )
436+ self . signal_used_queue ( STATS_INDEX )
432437 } else {
433438 error ! ( "Failed to update balloon stats, missing descriptor." ) ;
434439 Ok ( ( ) )
@@ -440,7 +445,7 @@ impl Balloon {
440445 if self . is_activated ( ) {
441446 self . config_space . num_pages = mib_to_pages ( amount_mib) ?;
442447 self . interrupt_trigger ( )
443- . trigger_irq ( IrqType :: Config )
448+ . trigger ( VirtioInterruptType :: Config )
444449 . map_err ( BalloonError :: InterruptError )
445450 } else {
446451 Err ( BalloonError :: DeviceNotActive )
@@ -551,11 +556,12 @@ impl VirtioDevice for Balloon {
551556 & self . queue_evts
552557 }
553558
554- fn interrupt_trigger ( & self ) -> Arc < IrqTrigger > {
559+ fn interrupt_trigger ( & self ) -> & dyn VirtioInterrupt {
555560 self . device_state
556561 . active_state ( )
557562 . expect ( "Device is not activated" )
558- . 1
563+ . interrupt
564+ . deref ( )
559565 }
560566
561567 fn read_config ( & self , offset : u64 , data : & mut [ u8 ] ) {
@@ -585,14 +591,14 @@ impl VirtioDevice for Balloon {
585591 fn activate (
586592 & mut self ,
587593 mem : GuestMemoryMmap ,
588- interrupt : Arc < IrqTrigger > ,
594+ interrupt : Arc < dyn VirtioInterrupt > ,
589595 ) -> Result < ( ) , ActivateError > {
590596 for q in self . queues . iter_mut ( ) {
591597 q. initialize ( & mem)
592598 . map_err ( ActivateError :: QueueMemoryError ) ?;
593599 }
594600
595- self . device_state = DeviceState :: Activated ( ( mem, interrupt) ) ;
601+ self . device_state = DeviceState :: Activated ( ActiveState { mem, interrupt } ) ;
596602 if self . activate_evt . write ( 1 ) . is_err ( ) {
597603 METRICS . activate_fails . inc ( ) ;
598604 self . device_state = DeviceState :: Inactive ;
@@ -621,7 +627,7 @@ pub(crate) mod tests {
621627 check_request_completion, invoke_handler_for_queue_event, set_request,
622628 } ;
623629 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} ;
625631 use crate :: test_utils:: single_region_mem;
626632 use crate :: vstate:: memory:: GuestAddress ;
627633
@@ -798,11 +804,10 @@ pub(crate) mod tests {
798804 fn test_invalid_request ( ) {
799805 let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
800806 let mem = default_mem ( ) ;
801- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
802807 // Only initialize the inflate queue to demonstrate invalid request handling.
803808 let infq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
804809 balloon. set_queue ( INFLATE_INDEX , infq. create_queue ( ) ) ;
805- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
810+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
806811
807812 // Fill the second page with non-zero bytes.
808813 for i in 0 ..0x1000 {
@@ -858,10 +863,9 @@ pub(crate) mod tests {
858863 fn test_inflate ( ) {
859864 let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
860865 let mem = default_mem ( ) ;
861- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
862866 let infq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
863867 balloon. set_queue ( INFLATE_INDEX , infq. create_queue ( ) ) ;
864- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
868+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
865869
866870 // Fill the third page with non-zero bytes.
867871 for i in 0 ..0x1000 {
@@ -929,10 +933,9 @@ pub(crate) mod tests {
929933 fn test_deflate ( ) {
930934 let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
931935 let mem = default_mem ( ) ;
932- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
933936 let defq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
934937 balloon. set_queue ( DEFLATE_INDEX , defq. create_queue ( ) ) ;
935- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
938+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
936939
937940 let page_addr = 0x10 ;
938941
@@ -978,10 +981,9 @@ pub(crate) mod tests {
978981 fn test_stats ( ) {
979982 let mut balloon = Balloon :: new ( 0 , true , 1 , false ) . unwrap ( ) ;
980983 let mem = default_mem ( ) ;
981- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
982984 let statsq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
983985 balloon. set_queue ( STATS_INDEX , statsq. create_queue ( ) ) ;
984- balloon. activate ( mem. clone ( ) , interrupt ) . unwrap ( ) ;
986+ balloon. activate ( mem. clone ( ) , default_interrupt ( ) ) . unwrap ( ) ;
985987
986988 let page_addr = 0x100 ;
987989
@@ -1057,7 +1059,9 @@ pub(crate) mod tests {
10571059 assert!( balloon. stats_desc_index. is_some( ) ) ;
10581060 balloon. process_stats_timer_event( ) . unwrap( ) ;
10591061 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+ ) ) ;
10611065 } ) ;
10621066 }
10631067 }
@@ -1066,23 +1070,21 @@ pub(crate) mod tests {
10661070 fn test_process_balloon_queues ( ) {
10671071 let mut balloon = Balloon :: new ( 0x10 , true , 0 , false ) . unwrap ( ) ;
10681072 let mem = default_mem ( ) ;
1069- let interrupt = Arc :: new ( IrqTrigger :: new ( ) . unwrap ( ) ) ;
10701073 let infq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
10711074 let defq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 16 ) ;
10721075
10731076 balloon. set_queue ( INFLATE_INDEX , infq. create_queue ( ) ) ;
10741077 balloon. set_queue ( DEFLATE_INDEX , defq. create_queue ( ) ) ;
10751078
1076- balloon. activate ( mem, interrupt ) . unwrap ( ) ;
1079+ balloon. activate ( mem, default_interrupt ( ) ) . unwrap ( ) ;
10771080 balloon. process_virtio_queues ( )
10781081 }
10791082
10801083 #[ test]
10811084 fn test_update_stats_interval ( ) {
10821085 let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
10831086 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 ( ) ;
10861088 assert_eq ! (
10871089 format!( "{:?}" , balloon. update_stats_polling_interval( 1 ) ) ,
10881090 "Err(StatisticsStateChange)"
@@ -1091,8 +1093,7 @@ pub(crate) mod tests {
10911093
10921094 let mut balloon = Balloon :: new ( 0 , true , 1 , false ) . unwrap ( ) ;
10931095 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 ( ) ;
10961097 assert_eq ! (
10971098 format!( "{:?}" , balloon. update_stats_polling_interval( 0 ) ) ,
10981099 "Err(StatisticsStateChange)"
@@ -1112,8 +1113,10 @@ pub(crate) mod tests {
11121113 fn test_num_pages ( ) {
11131114 let mut balloon = Balloon :: new ( 0 , true , 0 , false ) . unwrap ( ) ;
11141115 // 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+ } ) ;
11171120
11181121 assert_eq ! ( balloon. num_pages( ) , 0 ) ;
11191122 assert_eq ! ( balloon. actual_pages( ) , 0 ) ;
0 commit comments