@@ -81,6 +81,8 @@ pub struct RxBuffer {
81
81
pub iovecs : IovRingBuffer ,
82
82
// Ring buffer of meta data about descriptor chains stored in the `iov_ring`.
83
83
pub chain_infos : RingBuffer < ChainInfo > ,
84
+ // Total capacity this buffer holds.
85
+ pub total_capacity : u32 ,
84
86
// Number of descriptor chains we have used to process packets.
85
87
pub used_descriptors : u16 ,
86
88
}
@@ -92,6 +94,7 @@ impl RxBuffer {
92
94
iovecs : IovRingBuffer :: new ( ) ?,
93
95
chain_infos : RingBuffer :: new_with_size ( u32:: from ( FIRECRACKER_MAX_QUEUE_SIZE ) ) ,
94
96
used_descriptors : 0 ,
97
+ total_capacity : 0 ,
95
98
} )
96
99
}
97
100
@@ -113,8 +116,12 @@ impl RxBuffer {
113
116
114
117
/// Returns a slice of underlying iovec for the all chains
115
118
/// in the buffer.
116
- pub fn all_chains_mut_slice ( & mut self ) -> & mut [ iovec ] {
117
- self . iovecs . as_mut_slice ( )
119
+ pub fn all_chains_mut_slice ( & mut self ) -> Option < & mut [ iovec ] > {
120
+ if self . total_capacity < u32:: from ( u16:: MAX ) {
121
+ None
122
+ } else {
123
+ Some ( self . iovecs . as_mut_slice ( ) )
124
+ }
118
125
}
119
126
120
127
/// Add a new `DescriptorChain` that we received from the RX queue in the buffer.
@@ -171,6 +178,7 @@ impl RxBuffer {
171
178
chain_len,
172
179
chain_capacity,
173
180
} ) ;
181
+ self . total_capacity += chain_capacity;
174
182
175
183
Ok ( ( ) )
176
184
}
@@ -235,6 +243,7 @@ impl RxBuffer {
235
243
. pop_front ( )
236
244
. expect ( "This should never happen if write to the buffer succeded." ) ;
237
245
self . iovecs . pop_front ( usize:: from ( iov_info. chain_len ) ) ;
246
+ self . total_capacity -= iov_info. chain_capacity ;
238
247
239
248
if bytes_written <= iov_info. chain_capacity {
240
249
write_used ( iov_info. head_index , bytes_written, rx_queue) ;
@@ -282,7 +291,7 @@ mod tests {
282
291
283
292
#[ test]
284
293
fn test_rx_buffer_add_chain ( ) {
285
- let mem = single_region_mem ( 65562 ) ;
294
+ let mem = single_region_mem ( 65562 * 2 ) ;
286
295
let rxq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 256 ) ;
287
296
let mut queue = rxq. create_queue ( ) ;
288
297
@@ -317,9 +326,10 @@ mod tests {
317
326
) ;
318
327
}
319
328
320
- // 16 chains of len 1
329
+ // 64 chains of len 1 and size 1024
330
+ // in total 64K
321
331
{
322
- let chains = 16 ;
332
+ let chains = 64 ;
323
333
set_dtable_many_chains ( & rxq, chains) ;
324
334
queue. next_avail = Wrapping ( 0 ) ;
325
335
let mut buff = RxBuffer :: new ( ) . unwrap ( ) ;
@@ -329,7 +339,7 @@ mod tests {
329
339
buff. add_chain ( & mem, desc) . unwrap ( ) ;
330
340
}
331
341
}
332
- let slice = buff. all_chains_mut_slice ( ) ;
342
+ let slice = buff. all_chains_mut_slice ( ) . unwrap ( ) ;
333
343
for i in 0 ..chains {
334
344
assert_eq ! (
335
345
slice[ i] . iov_base as u64 ,
@@ -338,7 +348,7 @@ mod tests {
338
348
) ;
339
349
assert_eq ! ( slice[ i] . iov_len, 1024 ) ;
340
350
}
341
- assert_eq ! ( buff. chain_infos. len( ) , 16 ) ;
351
+ assert_eq ! ( buff. chain_infos. len( ) , chains as u32 ) ;
342
352
for ( i, ci) in buff. chain_infos . items [ 0 ..16 ] . iter ( ) . enumerate ( ) {
343
353
assert_eq ! (
344
354
* ci,
@@ -407,11 +417,11 @@ mod tests {
407
417
408
418
#[ test]
409
419
fn test_rx_buffer_write_mrg_buf ( ) {
410
- let mem = single_region_mem ( 65562 ) ;
420
+ let mem = single_region_mem ( 65562 * 2 ) ;
411
421
let rxq = VirtQueue :: new ( GuestAddress ( 0 ) , & mem, 256 ) ;
412
422
let mut queue = rxq. create_queue ( ) ;
413
423
414
- set_dtable_many_chains ( & rxq, 2 ) ;
424
+ set_dtable_many_chains ( & rxq, 64 ) ;
415
425
416
426
let mut buff = RxBuffer :: new ( ) . unwrap ( ) ;
417
427
while let Some ( desc) = queue. pop ( ) {
@@ -422,7 +432,7 @@ mod tests {
422
432
}
423
433
424
434
// Initially data should be all zeros
425
- let slice = buff. all_chains_mut_slice ( ) ;
435
+ let slice = buff. all_chains_mut_slice ( ) . unwrap ( ) ;
426
436
let data_slice_before: & [ u8 ] =
427
437
// SAFETY: safe as iovecs are verified on creation.
428
438
unsafe { std:: slice:: from_raw_parts ( slice[ 0 ] . iov_base . cast ( ) , slice[ 0 ] . iov_len ) } ;
@@ -435,7 +445,7 @@ mod tests {
435
445
// Write should hapepn to all 2 iovecs
436
446
buff. write ( & [ 69 ; 2 * 1024 ] ) . unwrap ( ) ;
437
447
438
- let slice = buff. all_chains_mut_slice ( ) ;
448
+ let slice = buff. all_chains_mut_slice ( ) . unwrap ( ) ;
439
449
let data_slice_after: & [ u8 ] =
440
450
// SAFETY: safe as iovecs are verified on creation.
441
451
unsafe { std:: slice:: from_raw_parts ( slice[ 0 ] . iov_base . cast ( ) , slice[ 0 ] . iov_len ) } ;
0 commit comments