@@ -524,6 +524,8 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
524
524
test -> nb_sockets = 1 ;
525
525
test -> fail = false;
526
526
test -> set_ring = false;
527
+ test -> adjust_tail = false;
528
+ test -> adjust_tail_support = false;
527
529
test -> mtu = MAX_ETH_PKT_SIZE ;
528
530
test -> xdp_prog_rx = ifobj_rx -> xdp_progs -> progs .xsk_def_prog ;
529
531
test -> xskmap_rx = ifobj_rx -> xdp_progs -> maps .xsk ;
@@ -757,14 +759,15 @@ static struct pkt_stream *pkt_stream_clone(struct pkt_stream *pkt_stream)
757
759
return pkt_stream_generate (pkt_stream -> nb_pkts , pkt_stream -> pkts [0 ].len );
758
760
}
759
761
760
- static void pkt_stream_replace (struct test_spec * test , u32 nb_pkts , u32 pkt_len )
762
+ static void pkt_stream_replace_ifobject (struct ifobject * ifobj , u32 nb_pkts , u32 pkt_len )
761
763
{
762
- struct pkt_stream * pkt_stream ;
764
+ ifobj -> xsk -> pkt_stream = pkt_stream_generate (nb_pkts , pkt_len );
765
+ }
763
766
764
- pkt_stream = pkt_stream_generate ( nb_pkts , pkt_len );
765
- test -> ifobj_tx -> xsk -> pkt_stream = pkt_stream ;
766
- pkt_stream = pkt_stream_generate ( nb_pkts , pkt_len );
767
- test -> ifobj_rx -> xsk -> pkt_stream = pkt_stream ;
767
+ static void pkt_stream_replace ( struct test_spec * test , u32 nb_pkts , u32 pkt_len )
768
+ {
769
+ pkt_stream_replace_ifobject ( test -> ifobj_tx , nb_pkts , pkt_len );
770
+ pkt_stream_replace_ifobject ( test -> ifobj_rx , nb_pkts , pkt_len ) ;
768
771
}
769
772
770
773
static void __pkt_stream_replace_half (struct ifobject * ifobj , u32 pkt_len ,
@@ -991,6 +994,31 @@ static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
991
994
return true;
992
995
}
993
996
997
+ static bool is_adjust_tail_supported (struct xsk_xdp_progs * skel_rx )
998
+ {
999
+ struct bpf_map * data_map ;
1000
+ int adjust_value = 0 ;
1001
+ int key = 0 ;
1002
+ int ret ;
1003
+
1004
+ data_map = bpf_object__find_map_by_name (skel_rx -> obj , "xsk_xdp_.bss" );
1005
+ if (!data_map || !bpf_map__is_internal (data_map )) {
1006
+ ksft_print_msg ("Error: could not find bss section of XDP program\n" );
1007
+ exit_with_error (errno );
1008
+ }
1009
+
1010
+ ret = bpf_map_lookup_elem (bpf_map__fd (data_map ), & key , & adjust_value );
1011
+ if (ret ) {
1012
+ ksft_print_msg ("Error: bpf_map_lookup_elem failed with error %d\n" , ret );
1013
+ exit_with_error (errno );
1014
+ }
1015
+
1016
+ /* Set the 'adjust_value' variable to -EOPNOTSUPP in the XDP program if the adjust_tail
1017
+ * helper is not supported. Skip the adjust_tail test case in this scenario.
1018
+ */
1019
+ return adjust_value != - EOPNOTSUPP ;
1020
+ }
1021
+
994
1022
static bool is_frag_valid (struct xsk_umem_info * umem , u64 addr , u32 len , u32 expected_pkt_nb ,
995
1023
u32 bytes_processed )
996
1024
{
@@ -1767,8 +1795,13 @@ static void *worker_testapp_validate_rx(void *arg)
1767
1795
1768
1796
if (!err && ifobject -> validation_func )
1769
1797
err = ifobject -> validation_func (ifobject );
1770
- if (err )
1771
- report_failure (test );
1798
+
1799
+ if (err ) {
1800
+ if (test -> adjust_tail && !is_adjust_tail_supported (ifobject -> xdp_progs ))
1801
+ test -> adjust_tail_support = false;
1802
+ else
1803
+ report_failure (test );
1804
+ }
1772
1805
1773
1806
pthread_exit (NULL );
1774
1807
}
@@ -2515,6 +2548,71 @@ static int testapp_hw_sw_max_ring_size(struct test_spec *test)
2515
2548
return testapp_validate_traffic (test );
2516
2549
}
2517
2550
2551
+ static int testapp_xdp_adjust_tail (struct test_spec * test , int adjust_value )
2552
+ {
2553
+ struct xsk_xdp_progs * skel_rx = test -> ifobj_rx -> xdp_progs ;
2554
+ struct xsk_xdp_progs * skel_tx = test -> ifobj_tx -> xdp_progs ;
2555
+
2556
+ test_spec_set_xdp_prog (test , skel_rx -> progs .xsk_xdp_adjust_tail ,
2557
+ skel_tx -> progs .xsk_xdp_adjust_tail ,
2558
+ skel_rx -> maps .xsk , skel_tx -> maps .xsk );
2559
+
2560
+ skel_rx -> bss -> adjust_value = adjust_value ;
2561
+
2562
+ return testapp_validate_traffic (test );
2563
+ }
2564
+
2565
+ static int testapp_adjust_tail (struct test_spec * test , u32 value , u32 pkt_len )
2566
+ {
2567
+ int ret ;
2568
+
2569
+ test -> adjust_tail_support = true;
2570
+ test -> adjust_tail = true;
2571
+ test -> total_steps = 1 ;
2572
+
2573
+ pkt_stream_replace_ifobject (test -> ifobj_tx , DEFAULT_BATCH_SIZE , pkt_len );
2574
+ pkt_stream_replace_ifobject (test -> ifobj_rx , DEFAULT_BATCH_SIZE , pkt_len + value );
2575
+
2576
+ ret = testapp_xdp_adjust_tail (test , value );
2577
+ if (ret )
2578
+ return ret ;
2579
+
2580
+ if (!test -> adjust_tail_support ) {
2581
+ ksft_test_result_skip ("%s %sResize pkt with bpf_xdp_adjust_tail() not supported\n" ,
2582
+ mode_string (test ), busy_poll_string (test ));
2583
+ return TEST_SKIP ;
2584
+ }
2585
+
2586
+ return 0 ;
2587
+ }
2588
+
2589
+ static int testapp_adjust_tail_shrink (struct test_spec * test )
2590
+ {
2591
+ /* Shrink by 4 bytes for testing purpose */
2592
+ return testapp_adjust_tail (test , -4 , MIN_PKT_SIZE * 2 );
2593
+ }
2594
+
2595
+ static int testapp_adjust_tail_shrink_mb (struct test_spec * test )
2596
+ {
2597
+ test -> mtu = MAX_ETH_JUMBO_SIZE ;
2598
+ /* Shrink by the frag size */
2599
+ return testapp_adjust_tail (test , - XSK_UMEM__MAX_FRAME_SIZE , XSK_UMEM__LARGE_FRAME_SIZE * 2 );
2600
+ }
2601
+
2602
+ static int testapp_adjust_tail_grow (struct test_spec * test )
2603
+ {
2604
+ /* Grow by 4 bytes for testing purpose */
2605
+ return testapp_adjust_tail (test , 4 , MIN_PKT_SIZE * 2 );
2606
+ }
2607
+
2608
+ static int testapp_adjust_tail_grow_mb (struct test_spec * test )
2609
+ {
2610
+ test -> mtu = MAX_ETH_JUMBO_SIZE ;
2611
+ /* Grow by (frag_size - last_frag_Size) - 1 to stay inside the last fragment */
2612
+ return testapp_adjust_tail (test , (XSK_UMEM__MAX_FRAME_SIZE / 2 ) - 1 ,
2613
+ XSK_UMEM__LARGE_FRAME_SIZE * 2 );
2614
+ }
2615
+
2518
2616
static void run_pkt_test (struct test_spec * test )
2519
2617
{
2520
2618
int ret ;
@@ -2621,6 +2719,10 @@ static const struct test_spec tests[] = {
2621
2719
{.name = "TOO_MANY_FRAGS" , .test_func = testapp_too_many_frags },
2622
2720
{.name = "HW_SW_MIN_RING_SIZE" , .test_func = testapp_hw_sw_min_ring_size },
2623
2721
{.name = "HW_SW_MAX_RING_SIZE" , .test_func = testapp_hw_sw_max_ring_size },
2722
+ {.name = "XDP_ADJUST_TAIL_SHRINK" , .test_func = testapp_adjust_tail_shrink },
2723
+ {.name = "XDP_ADJUST_TAIL_SHRINK_MULTI_BUFF" , .test_func = testapp_adjust_tail_shrink_mb },
2724
+ {.name = "XDP_ADJUST_TAIL_GROW" , .test_func = testapp_adjust_tail_grow },
2725
+ {.name = "XDP_ADJUST_TAIL_GROW_MULTI_BUFF" , .test_func = testapp_adjust_tail_grow_mb },
2624
2726
};
2625
2727
2626
2728
static void print_tests (void )
0 commit comments