@@ -20,7 +20,7 @@ use crate::devices::virtio::gen::virtio_blk::VIRTIO_F_VERSION_1;
20
20
use crate :: devices:: virtio:: gen:: virtio_net:: {
21
21
virtio_net_hdr_v1, VIRTIO_NET_F_CSUM , VIRTIO_NET_F_GUEST_CSUM , VIRTIO_NET_F_GUEST_TSO4 ,
22
22
VIRTIO_NET_F_GUEST_TSO6 , VIRTIO_NET_F_GUEST_UFO , VIRTIO_NET_F_HOST_TSO4 ,
23
- VIRTIO_NET_F_HOST_TSO6 , VIRTIO_NET_F_HOST_UFO , VIRTIO_NET_F_MAC ,
23
+ VIRTIO_NET_F_HOST_TSO6 , VIRTIO_NET_F_HOST_UFO , VIRTIO_NET_F_MAC , VIRTIO_NET_F_MRG_RXBUF ,
24
24
} ;
25
25
use crate :: devices:: virtio:: gen:: virtio_ring:: VIRTIO_RING_F_EVENT_IDX ;
26
26
use crate :: devices:: virtio:: iovec:: IoVecBuffer ;
@@ -150,6 +150,7 @@ impl Net {
150
150
| 1 << VIRTIO_NET_F_HOST_TSO6
151
151
| 1 << VIRTIO_NET_F_HOST_UFO
152
152
| 1 << VIRTIO_F_VERSION_1
153
+ | 1 << VIRTIO_NET_F_MRG_RXBUF
153
154
| 1 << VIRTIO_RING_F_EVENT_IDX ;
154
155
155
156
let mut config_space = ConfigSpace :: default ( ) ;
@@ -646,7 +647,11 @@ impl Net {
646
647
}
647
648
648
649
fn read_tap ( & mut self ) -> std:: io:: Result < usize > {
649
- self . tap . read_iovec ( self . rx_buffer . one_chain_mut_slice ( ) )
650
+ if self . has_feature ( u64:: from ( VIRTIO_NET_F_MRG_RXBUF ) ) {
651
+ self . tap . read_iovec ( self . rx_buffer . all_chains_mut_slice ( ) )
652
+ } else {
653
+ self . tap . read_iovec ( self . rx_buffer . one_chain_mut_slice ( ) )
654
+ }
650
655
}
651
656
652
657
/// Process a single RX queue event.
@@ -858,7 +863,7 @@ pub mod tests {
858
863
use crate :: devices:: virtio:: net:: device:: {
859
864
frame_bytes_from_buf, frame_bytes_from_buf_mut, frame_hdr_len, init_vnet_hdr, vnet_hdr_len,
860
865
} ;
861
- use crate :: devices:: virtio:: net:: rx_buffer:: ChainInfo ;
866
+ use crate :: devices:: virtio:: net:: rx_buffer:: { header_set_num_buffers , ChainInfo } ;
862
867
use crate :: devices:: virtio:: net:: test_utils:: test:: TestHelper ;
863
868
use crate :: devices:: virtio:: net:: test_utils:: {
864
869
default_net, if_index, inject_tap_tx_frame, set_mac, NetEvent , NetQueue ,
@@ -925,6 +930,7 @@ pub mod tests {
925
930
| 1 << VIRTIO_NET_F_HOST_TSO6
926
931
| 1 << VIRTIO_NET_F_HOST_UFO
927
932
| 1 << VIRTIO_F_VERSION_1
933
+ | 1 << VIRTIO_NET_F_MRG_RXBUF
928
934
| 1 << VIRTIO_RING_F_EVENT_IDX ;
929
935
930
936
assert_eq ! (
@@ -1046,10 +1052,9 @@ pub mod tests {
1046
1052
assert_eq ! ( th. rxq. used. idx. get( ) , 0 ) ;
1047
1053
}
1048
1054
1049
- #[ test]
1050
- fn test_rx_read_only_descriptor ( ) {
1051
- let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1052
- let mut th = TestHelper :: get_default ( & mem) ;
1055
+ fn rx_read_only_descriptor ( mut th : TestHelper ) {
1056
+ // let mem = single_region_mem(2 * MAX_BUFFER_SIZE);
1057
+ // let mut th = TestHelper::get_default(&mem);
1053
1058
th. activate_net ( ) ;
1054
1059
1055
1060
th. add_desc_chain (
@@ -1068,9 +1073,22 @@ pub mod tests {
1068
1073
}
1069
1074
1070
1075
#[ test]
1071
- fn test_rx_partial_write ( ) {
1076
+ fn test_rx_read_only_descriptor ( ) {
1077
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1078
+ let th = TestHelper :: get_default ( & mem) ;
1079
+ rx_read_only_descriptor ( th) ;
1080
+ }
1081
+
1082
+ #[ test]
1083
+ fn test_rx_read_only_descriptor_mrg_buf ( ) {
1072
1084
let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1073
1085
let mut th = TestHelper :: get_default ( & mem) ;
1086
+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1087
+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1088
+ rx_read_only_descriptor ( th) ;
1089
+ }
1090
+
1091
+ fn rx_partial_write ( mut th : TestHelper ) {
1074
1092
th. activate_net ( ) ;
1075
1093
1076
1094
// The descriptor chain is created so that the last descriptor doesn't fit in the
@@ -1092,9 +1110,22 @@ pub mod tests {
1092
1110
}
1093
1111
1094
1112
#[ test]
1095
- fn test_rx_retry ( ) {
1113
+ fn test_rx_partial_write ( ) {
1114
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1115
+ let th = TestHelper :: get_default ( & mem) ;
1116
+ rx_partial_write ( th) ;
1117
+ }
1118
+
1119
+ #[ test]
1120
+ fn test_rx_partial_write_mrg_buf ( ) {
1096
1121
let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1097
1122
let mut th = TestHelper :: get_default ( & mem) ;
1123
+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1124
+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1125
+ rx_partial_write ( th) ;
1126
+ }
1127
+
1128
+ fn rx_retry ( mut th : TestHelper ) {
1098
1129
th. activate_net ( ) ;
1099
1130
1100
1131
// Even though too short descriptor chains are also
@@ -1144,9 +1175,22 @@ pub mod tests {
1144
1175
}
1145
1176
1146
1177
#[ test]
1147
- fn test_rx_complex_desc_chain ( ) {
1178
+ fn test_rx_retry ( ) {
1179
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1180
+ let th = TestHelper :: get_default ( & mem) ;
1181
+ rx_retry ( th) ;
1182
+ }
1183
+
1184
+ #[ test]
1185
+ fn test_rx_retry_mrg_buf ( ) {
1148
1186
let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1149
1187
let mut th = TestHelper :: get_default ( & mem) ;
1188
+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1189
+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1190
+ rx_retry ( th) ;
1191
+ }
1192
+
1193
+ fn rx_complex_desc_chain ( mut th : TestHelper ) {
1150
1194
th. activate_net ( ) ;
1151
1195
1152
1196
// Create a valid Rx avail descriptor chain with multiple descriptors.
@@ -1183,9 +1227,22 @@ pub mod tests {
1183
1227
}
1184
1228
1185
1229
#[ test]
1186
- fn test_rx_multiple_frames ( ) {
1230
+ fn test_rx_complex_desc_chain ( ) {
1231
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1232
+ let th = TestHelper :: get_default ( & mem) ;
1233
+ rx_complex_desc_chain ( th) ;
1234
+ }
1235
+
1236
+ #[ test]
1237
+ fn test_rx_complex_desc_chain_mrg_buf ( ) {
1187
1238
let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1188
1239
let mut th = TestHelper :: get_default ( & mem) ;
1240
+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1241
+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1242
+ rx_complex_desc_chain ( th) ;
1243
+ }
1244
+
1245
+ fn rx_multiple_frames ( mut th : TestHelper ) {
1189
1246
th. activate_net ( ) ;
1190
1247
1191
1248
// Create 2 valid Rx avail descriptor chains. Each one has enough space to fit the
@@ -1226,6 +1283,70 @@ pub mod tests {
1226
1283
th. rxq . dtable [ 3 ] . check_data ( & [ 0 ; 500 ] ) ;
1227
1284
}
1228
1285
1286
+ #[ test]
1287
+ fn test_rx_multiple_frames ( ) {
1288
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1289
+ let th = TestHelper :: get_default ( & mem) ;
1290
+ rx_multiple_frames ( th) ;
1291
+ }
1292
+
1293
+ #[ test]
1294
+ fn test_rx_multiple_frames_mrg_buf ( ) {
1295
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1296
+ let mut th = TestHelper :: get_default ( & mem) ;
1297
+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1298
+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1299
+ rx_multiple_frames ( th) ;
1300
+ }
1301
+
1302
+ #[ test]
1303
+ fn test_rx_multiple_frames_mrg ( ) {
1304
+ let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
1305
+ let mut th = TestHelper :: get_default ( & mem) ;
1306
+
1307
+ // VIRTIO_NET_F_MRG_RXBUF is not enabled by default
1308
+ th. net ( ) . acked_features = 1 << VIRTIO_NET_F_MRG_RXBUF ;
1309
+
1310
+ th. activate_net ( ) ;
1311
+
1312
+ // Create 2 valid avail descriptor chains. We will send
1313
+ // one packet that shuld be split amound these 2 chains.
1314
+ th. add_desc_chain (
1315
+ NetQueue :: Rx ,
1316
+ 0 ,
1317
+ & [ ( 0 , 100 , VIRTQ_DESC_F_WRITE ) , ( 1 , 100 , VIRTQ_DESC_F_WRITE ) ] ,
1318
+ ) ;
1319
+ th. add_desc_chain (
1320
+ NetQueue :: Rx ,
1321
+ 1000 ,
1322
+ & [ ( 2 , 100 , VIRTQ_DESC_F_WRITE ) , ( 3 , 100 , VIRTQ_DESC_F_WRITE ) ] ,
1323
+ ) ;
1324
+ // Inject frame into tap and run epoll.
1325
+ let mut frame = inject_tap_tx_frame ( & th. net ( ) , 400 ) ;
1326
+ // SAFETY: frame is big enough and has correct alingment.
1327
+ unsafe {
1328
+ header_set_num_buffers ( frame. as_mut_ptr ( ) . cast ( ) , 2 ) ;
1329
+ }
1330
+ check_metric_after_block ! (
1331
+ th. net( ) . metrics. rx_packets_count,
1332
+ 1 ,
1333
+ th. event_manager. run_with_timeout( 100 ) . unwrap( )
1334
+ ) ;
1335
+
1336
+ // Check that the frame wasn't deferred.
1337
+ assert ! ( th. net( ) . deferred_rx_bytes. is_none( ) ) ;
1338
+ // Check that the used queue has advanced.
1339
+ assert_eq ! ( th. rxq. used. idx. get( ) , 2 ) ;
1340
+ assert ! ( & th. net( ) . irq_trigger. has_pending_irq( IrqType :: Vring ) ) ;
1341
+ // Check that the frame was written successfully into both descriptor chains.
1342
+ th. rxq . check_used_elem ( 0 , 0 , 200 ) ;
1343
+ th. rxq . check_used_elem ( 1 , 2 , 200 ) ;
1344
+ th. rxq . dtable [ 0 ] . check_data ( & frame[ 0 ..100 ] ) ;
1345
+ th. rxq . dtable [ 1 ] . check_data ( & frame[ 100 ..200 ] ) ;
1346
+ th. rxq . dtable [ 2 ] . check_data ( & frame[ 200 ..300 ] ) ;
1347
+ th. rxq . dtable [ 3 ] . check_data ( & frame[ 300 ..400 ] ) ;
1348
+ }
1349
+
1229
1350
#[ test]
1230
1351
fn test_tx_missing_queue_signal ( ) {
1231
1352
let mem = single_region_mem ( 2 * MAX_BUFFER_SIZE ) ;
@@ -1520,6 +1641,7 @@ pub mod tests {
1520
1641
net. rx_buffer . chain_infos . push_back ( ChainInfo {
1521
1642
head_index : 0 ,
1522
1643
chain_len : 1 ,
1644
+ chain_capacity : 128 ,
1523
1645
} ) ;
1524
1646
1525
1647
let src_mac = MacAddr :: from_str ( "11:11:11:11:11:11" ) . unwrap ( ) ;
0 commit comments