@@ -18,16 +18,10 @@ use alloc::vec;
1818use alloc:: vec:: Vec ;
1919
2020use bytes:: Bytes ;
21+ use fixedbitset:: FixedBitSet ;
2122
2223use super :: * ;
2324
24- /// In-flight entry tracking.
25- ///
26- /// Stored per descriptor ID while the entry is being processed.
27- /// Tracks that a descriptor slot is occupied.
28- #[ derive( Debug , Clone , Copy ) ]
29- pub ( crate ) struct Inflight ;
30-
3125/// Data received from the producer, safely copied out of shared memory.
3226///
3327/// Created by [`VirtqConsumer::poll`]. The entry data is eagerly copied
@@ -261,7 +255,7 @@ impl AckCompletion {
261255pub struct VirtqConsumer < M , N > {
262256 inner : RingConsumer < M > ,
263257 notifier : N ,
264- inflight : Vec < Option < Inflight > > ,
258+ inflight : FixedBitSet ,
265259}
266260
267261impl < M : MemOps + Clone , N : Notifier > VirtqConsumer < M , N > {
@@ -274,7 +268,7 @@ impl<M: MemOps + Clone, N: Notifier> VirtqConsumer<M, N> {
274268 /// * `notifier` - Callback for notifying the driver (producer) about completions
275269 pub fn new ( layout : Layout , mem : M , notifier : N ) -> Self {
276270 let inner = RingConsumer :: new ( layout, mem) ;
277- let inflight = vec ! [ None ; inner. len( ) ] ;
271+ let inflight = FixedBitSet :: with_capacity ( inner. len ( ) ) ;
278272
279273 Self {
280274 inner,
@@ -320,16 +314,16 @@ impl<M: MemOps + Clone, N: Notifier> VirtqConsumer<M, N> {
320314 }
321315
322316 // Reserve the inflight slot
323- let slot = self
324- . inflight
325- . get_mut ( id as usize )
326- . ok_or ( VirtqError :: InvalidState ) ? ;
317+ let id_idx = id as usize ;
318+ if id_idx >= self . inflight . len ( ) {
319+ return Err ( VirtqError :: InvalidState ) ;
320+ }
327321
328- if slot . is_some ( ) {
322+ if self . inflight . contains ( id_idx ) {
329323 return Err ( VirtqError :: InvalidState ) ;
330324 }
331325
332- * slot = Some ( Inflight ) ;
326+ self . inflight . insert ( id_idx ) ;
333327 let token = Token ( id) ;
334328
335329 // Copy entry data from shared memory
@@ -363,16 +357,13 @@ impl<M: MemOps + Clone, N: Notifier> VirtqConsumer<M, N> {
363357 let id = completion. id ( ) ;
364358 let written = completion. written ( ) as u32 ;
365359
366- let slot = self
367- . inflight
368- . get_mut ( id as usize )
369- . ok_or ( VirtqError :: InvalidState ) ?;
370-
371- if slot. is_none ( ) {
360+ let id_idx = id as usize ;
361+ let slot_set = id_idx < self . inflight . len ( ) && self . inflight . contains ( id_idx) ;
362+ if !slot_set {
372363 return Err ( VirtqError :: InvalidState ) ;
373364 }
374365
375- * slot = None ;
366+ self . inflight . set ( id_idx , false ) ;
376367
377368 if self . inner . submit_used_with_notify ( id, written) ? {
378369 self . notifier . notify ( QueueStats {
@@ -445,7 +436,7 @@ impl<M: MemOps + Clone, N: Notifier> VirtqConsumer<M, N> {
445436 /// Reset ring and inflight state to initial values.
446437 pub fn reset ( & mut self ) {
447438 self . inner . reset ( ) ;
448- self . inflight . fill ( None ) ;
439+ self . inflight . clear ( ) ;
449440 }
450441}
451442
@@ -647,14 +638,14 @@ mod tests {
647638 producer. submit ( se) . unwrap ( ) ;
648639
649640 let ( _entry, completion) = consumer. poll ( 1024 ) . unwrap ( ) . unwrap ( ) ;
650- assert ! ( consumer. inflight. iter ( ) . any ( |s| s . is_some ( ) ) ) ;
641+ assert ! ( consumer. inflight. count_ones ( .. ) > 0 ) ;
651642
652643 // Complete first so we do not leak
653644 consumer. complete ( completion) . unwrap ( ) ;
654645
655646 consumer. reset ( ) ;
656647
657- assert ! ( consumer. inflight. iter ( ) . all ( |s| s . is_none ( ) ) ) ;
648+ assert_eq ! ( consumer. inflight. count_ones ( .. ) , 0 ) ;
658649 assert_eq ! ( consumer. inner. num_inflight( ) , 0 ) ;
659650 }
660651
@@ -677,7 +668,7 @@ mod tests {
677668
678669 consumer. reset ( ) ;
679670
680- assert ! ( consumer. inflight. iter ( ) . all ( |s| s . is_none ( ) ) ) ;
671+ assert_eq ! ( consumer. inflight. count_ones ( .. ) , 0 ) ;
681672 assert_eq ! ( consumer. inner. num_inflight( ) , 0 ) ;
682673 }
683674}
0 commit comments