99use std:: io:: Read ;
1010use std:: mem;
1111use std:: net:: Ipv4Addr ;
12+ use std:: os:: fd:: AsRawFd ;
1213use std:: sync:: atomic:: AtomicU32 ;
1314use std:: sync:: { Arc , Mutex } ;
1415
@@ -286,6 +287,7 @@ impl Net {
286287 } ;
287288
288289 if queue. prepare_kick ( mem) {
290+ // warn!("trigger: {:?}", queue_type);
289291 self . irq_trigger
290292 . trigger_irq ( IrqType :: Vring )
291293 . map_err ( |err| {
@@ -405,12 +407,19 @@ impl Net {
405407
406408 let queue = & mut self . queues [ RX_INDEX ] ;
407409
408- // let mut i = 0;
410+ let mut i = 0 ;
411+ let mut nd = 0 ;
409412 let mut bytes = & self . rx_frame_buf [ self . rx_bytes_send ..self . rx_bytes_read ] ;
410413 warn ! ( "queue size: {}" , queue. len( mem) ) ;
411- warn ! ( "do_write_frame_to_guest bytes len: {}" , bytes. len( ) ) ;
414+ warn ! (
415+ "do_write_frame_to_guest bytes s: {} e: {} len: {}" ,
416+ self . rx_bytes_send,
417+ self . rx_bytes_read,
418+ bytes. len( )
419+ ) ;
420+
412421 loop {
413- // i += 1;
422+ i += 1 ;
414423 // warn!("do_write_frame_to_guest iteration: {i}");
415424 let head_descriptor = queue. pop_or_enable_notification ( mem) . ok_or_else ( || {
416425 self . metrics . no_rx_avail_buffer . inc ( ) ;
@@ -469,6 +478,7 @@ impl Net {
469478 // self.rx_descriptors_used
470479 // );
471480
481+ nd = self . rx_descriptors_used ;
472482 self . rx_bytes_send = 0 ;
473483 self . rx_header_addr = None ;
474484 self . rx_descriptors_used = 0 ;
@@ -483,6 +493,7 @@ impl Net {
483493 }
484494 }
485495 }
496+ warn ! ( "used {i} descriptor chains, {nd} descriptors" ) ;
486497 Ok ( ( ) )
487498 }
488499
@@ -545,8 +556,15 @@ impl Net {
545556 }
546557
547558 let _metric = net_metrics. tap_write_agg . record_latency_metrics ( ) ;
559+ warn ! (
560+ "+++++++++++ writing to the tap iov with len: {} ++++++++" ,
561+ frame_iovec. iovec_count( )
562+ ) ;
563+ for v in frame_iovec. vecs . iter ( ) {
564+ warn ! ( "iov len: {}" , v. iov_len) ;
565+ }
548566 match Self :: write_tap ( tap, frame_iovec) {
549- Ok ( _ ) => {
567+ Ok ( l ) => {
550568 let len = u64:: from ( frame_iovec. len ( ) ) ;
551569 net_metrics. tx_bytes_count . add ( len) ;
552570 net_metrics. tx_packets_count . inc ( ) ;
@@ -574,20 +592,26 @@ impl Net {
574592 }
575593 } else {
576594 self . rx_bytes_read = self . read_tap ( ) . map_err ( NetError :: IO ) ?;
595+ warn ! ( "read {} bytes from tap" , self . rx_bytes_read) ;
577596 }
578597 Ok ( ( ) )
579598 }
580599
581600 fn process_rx ( & mut self ) -> Result < ( ) , DeviceError > {
582- // warn!("process_rx");
583- // Read as many frames as possible.
601+ self . process_rx_iov ( )
602+ }
584603
604+ fn process_rx_orig ( & mut self ) -> Result < ( ) , DeviceError > {
605+ warn ! ( "------- process_rx ----------" ) ;
585606 let t = std:: time:: Instant :: now ( ) ;
607+
608+ // Read as many frames as possible.
586609 loop {
587610 match self . read_from_mmds_or_tap ( ) {
588611 Ok ( _) => {
589612 self . metrics . rx_count . inc ( ) ;
590613 if !self . rate_limited_rx_single_frame ( ) {
614+ warn ! ( "setting deferred_frame" ) ;
591615 self . rx_deferred_frame = true ;
592616 break ;
593617 }
@@ -603,6 +627,7 @@ impl Net {
603627 return Err ( DeviceError :: FailedReadTap ) ;
604628 }
605629 } ;
630+ warn ! ( "net IO error: {:?}" , err) ;
606631 break ;
607632 }
608633 Err ( err) => {
@@ -617,9 +642,107 @@ impl Net {
617642 self . signal_used_queue ( NetQueue :: Rx )
618643 }
619644
645+ fn process_rx_iov ( & mut self ) -> Result < ( ) , DeviceError > {
646+ warn ! ( "------- process_rx ----------" ) ;
647+ let t = std:: time:: Instant :: now ( ) ;
648+
649+ let mem = self . device_state . mem ( ) . unwrap ( ) ;
650+
651+ let queue_len = self . queues [ RX_INDEX ] . len ( mem) ;
652+ warn ! ( "Queue len: {queue_len}" ) ;
653+ if queue_len == 0 {
654+ return Ok ( ( ) ) ;
655+ }
656+
657+ let mut used_heads = 0 ;
658+ loop {
659+ for _ in 0 ..used_heads {
660+ _ = self . queues [ RX_INDEX ] . pop ( mem) ;
661+ }
662+
663+ let mut the_iov = IoVecBuffer {
664+ vecs : Default :: default ( ) ,
665+ len : 0 ,
666+ } ;
667+ let mut index_iov = Vec :: new ( ) ;
668+ let mut q = 0 ;
669+ while let Some ( head_descriptor) = self . queues [ RX_INDEX ] . pop ( mem) {
670+ q += 1 ;
671+ let hi = head_descriptor. index ;
672+ let iov = IoVecBuffer :: from_descriptor_chain ( head_descriptor) . unwrap ( ) ;
673+ the_iov. vecs . extend_from_slice ( & iov. vecs ) ;
674+ the_iov. len += iov. len ;
675+ index_iov. push ( ( hi, iov) ) ;
676+ }
677+ for _ in 0 ..q {
678+ self . queues [ RX_INDEX ] . undo_pop ( ) ;
679+ }
680+ warn ! (
681+ "all_iov: vecs: {}, len: {}" ,
682+ the_iov. vecs. len( ) ,
683+ the_iov. len
684+ ) ;
685+ if index_iov. is_empty ( ) {
686+ return Ok ( ( ) ) ;
687+ }
688+
689+ match self . tap . read_iovec ( & the_iov) . map_err ( NetError :: IO ) {
690+ Ok ( mut bytes_written) => {
691+ warn ! ( "bytes written: {bytes_written}" ) ;
692+ let mut heads = 0 ;
693+ loop {
694+ if heads == index_iov. len ( ) {
695+ warn ! ( "exausted all {heads} iovecs" ) ;
696+ break ;
697+ }
698+
699+ let ( head_index, iov) = & index_iov[ heads] ;
700+
701+ if bytes_written < iov. len ( ) as usize {
702+ warn ! (
703+ "head with index: {head_index} used {bytes_written} out of {} bytes" ,
704+ iov. len( )
705+ ) ;
706+ _ = self . queues [ RX_INDEX ] . try_enable_notification ( mem) ;
707+ self . queues [ RX_INDEX ]
708+ . add_used ( mem, * head_index, bytes_written as u32 )
709+ . unwrap ( ) ;
710+ break ;
711+ } else {
712+ warn ! (
713+ "head with index: {head_index} used all out of {} bytes" ,
714+ iov. len( )
715+ ) ;
716+ _ = self . queues [ RX_INDEX ] . try_enable_notification ( mem) ;
717+ self . queues [ RX_INDEX ]
718+ . add_used ( mem, * head_index, iov. len ( ) )
719+ . unwrap ( ) ;
720+ bytes_written -= iov. len ( ) as usize ;
721+ } ;
722+ heads += 1 ;
723+ }
724+ warn ! ( "heads: {heads}" ) ;
725+ #[ allow( clippy:: transmute_ptr_to_ref) ]
726+ let header: & mut virtio_net_hdr_v1 =
727+ unsafe { std:: mem:: transmute ( the_iov. vecs [ 0 ] . iov_base ) } ;
728+ header. num_buffers = heads as u16 + 1 ;
729+ used_heads += heads + 1 ;
730+ }
731+ Err ( e) => {
732+ break ;
733+ }
734+ }
735+ }
736+
737+ warn ! ( "process_rx took: {}ns" , t. elapsed( ) . as_nanos( ) ) ;
738+
739+ self . signal_used_queue ( NetQueue :: Rx ) ?;
740+ Ok ( ( ) )
741+ }
742+
620743 // Process the deferred frame first, then continue reading from tap.
621744 fn handle_deferred_frame ( & mut self ) -> Result < ( ) , DeviceError > {
622- warn ! ( "handle_deferred_frame" ) ;
745+ // warn!("handle_deferred_frame");
623746 if self . rate_limited_rx_single_frame ( ) {
624747 self . rx_deferred_frame = false ;
625748 // process_rx() was interrupted possibly before consuming all
@@ -919,6 +1042,7 @@ impl VirtioDevice for Net {
9191042 }
9201043
9211044 fn activate ( & mut self , mem : GuestMemoryMmap ) -> Result < ( ) , ActivateError > {
1045+ // warn!("NET ACKED FEATURES: {:#x}", self.acked_features);
9221046 let event_idx = self . has_feature ( u64:: from ( VIRTIO_RING_F_EVENT_IDX ) ) ;
9231047 if event_idx {
9241048 for queue in & mut self . queues {
0 commit comments