@@ -197,6 +197,14 @@ impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
197197        self . state . avail_idx ( self . mem . memory ( ) . deref ( ) ,  order) 
198198    } 
199199
200+     /// Reads the `idx` field from the used ring. 
201+      /// 
202+      /// # Arguments 
203+      /// * `order` - the memory ordering used to access the `idx` field from memory. 
204+      pub  fn  used_idx ( & self ,  order :  Ordering )  -> Result < Wrapping < u16 > ,  Error >  { 
205+         self . state . used_idx ( self . mem . memory ( ) . deref ( ) ,  order) 
206+     } 
207+ 
200208    /// Put a used descriptor head into the used ring. 
201209     /// 
202210     /// # Arguments 
@@ -236,13 +244,26 @@ impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S> {
236244        self . state . next_avail ( ) 
237245    } 
238246
247+     /// Returns the index for the next descriptor in the used ring. 
248+      pub  fn  next_used ( & self )  -> u16  { 
249+         self . state . next_used ( ) 
250+     } 
251+ 
239252    /// Set the index of the next entry in the available ring. 
240253     /// 
241254     /// # Arguments 
242255     /// * `next_avail` - the index of the next available ring entry. 
243256     pub  fn  set_next_avail ( & mut  self ,  next_avail :  u16 )  { 
244257        self . state . set_next_avail ( next_avail) ; 
245258    } 
259+ 
260+     /// Sets the index for the next descriptor in the used ring. 
261+      /// 
262+      /// # Arguments 
263+      /// * `next_used` - the index of the next used ring entry. 
264+      pub  fn  set_next_used ( & mut  self ,  next_used :  u16 )  { 
265+         self . state . set_next_used ( next_used) ; 
266+     } 
246267} 
247268
248269impl < M :  GuestAddressSpace >  Queue < M ,  QueueState >  { 
@@ -348,6 +369,7 @@ mod tests {
348369        let  vq = MockSplitQueue :: new ( m,  16 ) ; 
349370        let  mut  q = vq. create_queue ( m) ; 
350371
372+         assert_eq ! ( q. used_idx( Ordering :: Acquire ) . unwrap( ) ,  Wrapping ( 0 ) ) ; 
351373        assert_eq ! ( u16 :: from_le( vq. used( ) . idx( ) . load( ) ) ,  0 ) ; 
352374
353375        // index too large 
@@ -357,6 +379,7 @@ mod tests {
357379        // should be ok 
358380        q. add_used ( 1 ,  0x1000 ) . unwrap ( ) ; 
359381        assert_eq ! ( q. state. next_used,  Wrapping ( 1 ) ) ; 
382+         assert_eq ! ( q. used_idx( Ordering :: Acquire ) . unwrap( ) ,  Wrapping ( 1 ) ) ; 
360383        assert_eq ! ( u16 :: from_le( vq. used( ) . idx( ) . load( ) ) ,  1 ) ; 
361384
362385        let  x = vq. used ( ) . ring ( ) . ref_at ( 0 ) . load ( ) ; 
@@ -377,7 +400,7 @@ mod tests {
377400        // Same for `event_idx_enabled`, `next_avail` `next_used` and `signalled_used`. 
378401        q. set_event_idx ( true ) ; 
379402        q. set_next_avail ( 2 ) ; 
380-         q. add_used ( 1 ,   200 ) . unwrap ( ) ; 
403+         q. set_next_used ( 4 ) ; 
381404        q. state . signalled_used  = Some ( Wrapping ( 15 ) ) ; 
382405        assert_eq ! ( q. state. size,  8 ) ; 
383406        // `create_queue` also marks the queue as ready. 
@@ -533,10 +556,14 @@ mod tests {
533556            i += 1 ; 
534557            q. disable_notification ( ) . unwrap ( ) ; 
535558
536-             while  let  Some ( _chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
559+             while  let  Some ( chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
537560                // Here the device would consume entries from the available ring, add an entry in 
538561                // the used ring and optionally notify the driver. For the purpose of this test, we 
539562                // don't need to do anything with the chain, only consume it. 
563+                 let  head_index = chain. head_index ( ) ; 
564+                 let  mut  desc_len = 0 ; 
565+                 chain. for_each ( |d| desc_len += d. len ( ) ) ; 
566+                 q. add_used ( head_index,  desc_len) . unwrap ( ) ; 
540567            } 
541568            if  !q. enable_notification ( ) . unwrap ( )  { 
542569                break ; 
@@ -547,6 +574,7 @@ mod tests {
547574        assert_eq ! ( i,  1 ) ; 
548575        // The next chain that can be consumed should have index 2. 
549576        assert_eq ! ( q. next_avail( ) ,  2 ) ; 
577+         assert_eq ! ( q. next_used( ) ,  2 ) ; 
550578        // Let the device know it can consume one more chain. 
551579        vq. avail ( ) . idx ( ) . store ( u16:: to_le ( 3 ) ) ; 
552580        i = 0 ; 
@@ -555,8 +583,12 @@ mod tests {
555583            i += 1 ; 
556584            q. disable_notification ( ) . unwrap ( ) ; 
557585
558-             while  let  Some ( _chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
586+             while  let  Some ( chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
559587                // In a real use case, we would do something with the chain here. 
588+                 let  head_index = chain. head_index ( ) ; 
589+                 let  mut  desc_len = 0 ; 
590+                 chain. for_each ( |d| desc_len += d. len ( ) ) ; 
591+                 q. add_used ( head_index,  desc_len) . unwrap ( ) ; 
560592            } 
561593
562594            // For the simplicity of the test we are updating here the `idx` value of the available 
@@ -571,21 +603,27 @@ mod tests {
571603        assert_eq ! ( i,  2 ) ; 
572604        // The next chain that can be consumed should have index 4. 
573605        assert_eq ! ( q. next_avail( ) ,  4 ) ; 
606+         assert_eq ! ( q. next_used( ) ,  4 ) ; 
574607
575608        // Set an `idx` that is bigger than the number of entries added in the ring. 
576609        // This is an allowed scenario, but the indexes of the chain will have unexpected values. 
577610        vq. avail ( ) . idx ( ) . store ( u16:: to_le ( 7 ) ) ; 
578611        loop  { 
579612            q. disable_notification ( ) . unwrap ( ) ; 
580613
581-             while  let  Some ( _chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
614+             while  let  Some ( chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
582615                // In a real use case, we would do something with the chain here. 
616+                 let  head_index = chain. head_index ( ) ; 
617+                 let  mut  desc_len = 0 ; 
618+                 chain. for_each ( |d| desc_len += d. len ( ) ) ; 
619+                 q. add_used ( head_index,  desc_len) . unwrap ( ) ; 
583620            } 
584621            if  !q. enable_notification ( ) . unwrap ( )  { 
585622                break ; 
586623            } 
587624        } 
588625        assert_eq ! ( q. next_avail( ) ,  7 ) ; 
626+         assert_eq ! ( q. next_used( ) ,  7 ) ; 
589627    } 
590628
591629    #[ test]  
@@ -619,14 +657,19 @@ mod tests {
619657        vq. avail ( ) . idx ( ) . store ( u16:: to_le ( 3 ) ) ; 
620658        // No descriptor chains are consumed at this point. 
621659        assert_eq ! ( q. next_avail( ) ,  0 ) ; 
660+         assert_eq ! ( q. next_used( ) ,  0 ) ; 
622661
623662        loop  { 
624663            q. disable_notification ( ) . unwrap ( ) ; 
625664
626-             while  let  Some ( _chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
665+             while  let  Some ( chain )  = q. iter ( ) . unwrap ( ) . next ( )  { 
627666                // Here the device would consume entries from the available ring, add an entry in 
628667                // the used ring and optionally notify the driver. For the purpose of this test, we 
629668                // don't need to do anything with the chain, only consume it. 
669+                 let  head_index = chain. head_index ( ) ; 
670+                 let  mut  desc_len = 0 ; 
671+                 chain. for_each ( |d| desc_len += d. len ( ) ) ; 
672+                 q. add_used ( head_index,  desc_len) . unwrap ( ) ; 
630673            } 
631674            if  !q. enable_notification ( ) . unwrap ( )  { 
632675                break ; 
@@ -635,6 +678,8 @@ mod tests {
635678        // The next chain that can be consumed should have index 3. 
636679        assert_eq ! ( q. next_avail( ) ,  3 ) ; 
637680        assert_eq ! ( q. avail_idx( Ordering :: Acquire ) . unwrap( ) ,  Wrapping ( 3 ) ) ; 
681+         assert_eq ! ( q. next_used( ) ,  3 ) ; 
682+         assert_eq ! ( q. used_idx( Ordering :: Acquire ) . unwrap( ) ,  Wrapping ( 3 ) ) ; 
638683        assert ! ( q. lock( ) . ready( ) ) ; 
639684
640685        // Decrement `idx` which should be forbidden. We don't enforce this thing, but we should 
0 commit comments