@@ -29,6 +29,7 @@ use utils::epoll::{EpollEvent, EventSet};
2929
3030use super :: device:: { Vsock , EVQ_INDEX , RXQ_INDEX , TXQ_INDEX } ;
3131use super :: VsockBackend ;
32+ use crate :: virtio:: DeviceState ;
3233
3334impl < B > Vsock < B >
3435where
@@ -191,24 +192,32 @@ where
191192 let backend = self . backend . as_raw_fd ( ) ;
192193 let activate_evt = self . activate_evt . as_raw_fd ( ) ;
193194
194- let mut raise_irq = false ;
195-
196- match source {
197- _ if source == rxq => raise_irq = self . handle_rxq_event ( event) ,
198- _ if source == txq => raise_irq = self . handle_txq_event ( event) ,
199- _ if source == evq => raise_irq = self . handle_evq_event ( event) ,
200- _ if source == backend => {
201- raise_irq = self . notify_backend ( event) ;
195+ match self . device_state {
196+ DeviceState :: Activated ( _) => {
197+ let mut raise_irq = false ;
198+
199+ match source {
200+ _ if source == rxq => raise_irq = self . handle_rxq_event ( event) ,
201+ _ if source == txq => raise_irq = self . handle_txq_event ( event) ,
202+ _ if source == evq => raise_irq = self . handle_evq_event ( event) ,
203+ _ if source == backend => {
204+ raise_irq = self . notify_backend ( event) ;
205+ }
206+ _ if source == activate_evt => {
207+ self . handle_activate_event ( event_manager) ;
208+ }
209+ _ => warn ! ( "Unexpected vsock event received: {:?}" , source) ,
210+ }
211+
212+ if raise_irq {
213+ self . signal_used_queue ( ) . unwrap_or_default ( ) ;
214+ }
202215 }
203- _ if source == activate_evt => {
204- self . handle_activate_event ( event_manager) ;
205- }
206- _ => warn ! ( "Unexpected vsock event received: {:?}" , source) ,
207- }
208-
209- if raise_irq {
210- self . signal_used_queue ( ) . unwrap_or_default ( ) ;
211- }
216+ DeviceState :: Inactive => warn ! (
217+ "Vsock: The device is not yet activated. Spurious event received: {:?}" ,
218+ source
219+ ) ,
220+ } ;
212221 }
213222
214223 fn interest_list ( & self ) -> Vec < EpollEvent > {
@@ -222,11 +231,13 @@ where
222231#[ cfg( test) ]
223232mod tests {
224233 use std:: sync:: atomic:: Ordering ;
234+ use std:: sync:: { Arc , Mutex } ;
225235
226- use super :: super :: tests:: TestContext ;
236+ use super :: super :: tests:: { EventHandlerContext , TestContext } ;
227237 use super :: super :: * ;
228238 use super :: * ;
229239
240+ use crate :: virtio:: device:: VirtioDevice ;
230241 use crate :: virtio:: vsock:: packet:: VSOCK_PKT_HDR_SIZE ;
231242 use crate :: virtio:: VIRTIO_MMIO_INT_VRING ;
232243 use crate :: Error as DeviceError ;
@@ -558,4 +569,70 @@ mod tests {
558569 GAP_SIZE as u32 + 100 ,
559570 ) ;
560571 }
572+
573+ #[ test]
574+ fn test_event_handler ( ) {
575+ let mut event_manager = EventManager :: new ( ) . unwrap ( ) ;
576+ let test_ctx = TestContext :: new ( ) ;
577+ let EventHandlerContext {
578+ device,
579+ guest_rxvq,
580+ guest_txvq,
581+ ..
582+ } = test_ctx. create_event_handler_context ( ) ;
583+
584+ let vsock = Arc :: new ( Mutex :: new ( device) ) ;
585+ event_manager. add_subscriber ( vsock. clone ( ) ) . unwrap ( ) ;
586+
587+ // Push a queue event
588+ // - the driver has something to send (there's data in the TX queue); and
589+ // - the backend has no pending RX data.
590+ {
591+ let mut device = vsock. lock ( ) . unwrap ( ) ;
592+ device. backend . set_pending_rx ( true ) ;
593+ device. queue_events [ TXQ_INDEX ] . write ( 1 ) . unwrap ( ) ;
594+ }
595+
596+ // EventManager should report no events since vsock has only registered
597+ // its activation event so far (even though there is also a queue event pending).
598+ let ev_count = event_manager. run_with_timeout ( 50 ) . unwrap ( ) ;
599+ assert_eq ! ( ev_count, 0 ) ;
600+
601+ // Manually force a queue event and check it's ignored pre-activation.
602+ {
603+ let mut device = vsock. lock ( ) . unwrap ( ) ;
604+
605+ let raw_txq_evt = device. queue_events [ TXQ_INDEX ] . as_raw_fd ( ) as u64 ;
606+ // Artificially push event.
607+ device. process (
608+ & EpollEvent :: new ( EventSet :: IN , raw_txq_evt) ,
609+ & mut event_manager,
610+ ) ;
611+
612+ // Both available RX and TX descriptors should be untouched.
613+ assert_eq ! ( guest_rxvq. used. idx. get( ) , 0 ) ;
614+ assert_eq ! ( guest_txvq. used. idx. get( ) , 0 ) ;
615+ }
616+
617+ // Now activate the device.
618+ vsock
619+ . lock ( )
620+ . unwrap ( )
621+ . activate ( test_ctx. mem . clone ( ) )
622+ . unwrap ( ) ;
623+ // Process the activate event.
624+ let ev_count = event_manager. run_with_timeout ( 50 ) . unwrap ( ) ;
625+ assert_eq ! ( ev_count, 1 ) ;
626+
627+ // Handle the previously pushed queue event through EventManager.
628+ {
629+ let ev_count = event_manager
630+ . run_with_timeout ( 100 )
631+ . expect ( "Metrics event timeout or error." ) ;
632+ assert_eq ! ( ev_count, 1 ) ;
633+ // Both available RX and TX descriptors should have been used.
634+ assert_eq ! ( guest_rxvq. used. idx. get( ) , 1 ) ;
635+ assert_eq ! ( guest_txvq. used. idx. get( ) , 1 ) ;
636+ }
637+ }
561638}
0 commit comments