Re: [PATCH bpf-next 10/10] selftests: xsk: add support for zero copy testing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jun 10, 2022 at 5:20 PM Maciej Fijalkowski
<maciej.fijalkowski@xxxxxxxxx> wrote:
>
> Introduce new mode to xdpxceiver responsible for testing AF_XDP zero
> copy support of driver that serves underlying physical device. When
> setting up test suite, determine whether driver has ZC support or not by
> trying to bind XSK ZC socket to the interface. If it succeeded,
> interpret it as ZC support being in place and do softirq and busy poll
> tests for zero copy mode.
>
> Note that Rx dropped tests are skipped since ZC path is not touching
> rx_dropped stat at all.

Great to be able to test zero-copy drivers. Thank you! Some small
comments below.

> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@xxxxxxxxx>
> ---
>  tools/testing/selftests/bpf/xdpxceiver.c | 80 ++++++++++++++++++++++--
>  tools/testing/selftests/bpf/xdpxceiver.h |  2 +
>  2 files changed, 77 insertions(+), 5 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c
> index a2aa652d0bb8..beef8d694fa6 100644
> --- a/tools/testing/selftests/bpf/xdpxceiver.c
> +++ b/tools/testing/selftests/bpf/xdpxceiver.c
> @@ -124,9 +124,20 @@ static void __exit_with_error(int error, const char *file, const char *func, int
>  }
>
>  #define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__)
> -
> -#define mode_string(test) (test)->ifobj_tx->xdp_flags & XDP_FLAGS_SKB_MODE ? "SKB" : "DRV"
>  #define busy_poll_string(test) (test)->ifobj_tx->busy_poll ? "BUSY-POLL " : ""
> +static char *mode_string(struct test_spec *test)
> +{
> +       switch (test->mode) {
> +       case TEST_MODE_SKB:
> +               return "SKB";
> +       case TEST_MODE_DRV:
> +               return "DRV";
> +       case TEST_MODE_ZC:
> +               return "ZC";
> +       default:
> +               return "BOGUS";
> +       }
> +}
>
>  static void report_failure(struct test_spec *test)
>  {
> @@ -317,6 +328,53 @@ static int __xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_i
>         return xsk_socket__create(&xsk->xsk, ifobject->ifname, 0, umem->umem, rxr, txr, &cfg);
>  }
>
> +static bool ifobj_zc_avail(struct ifobject *ifobject)
> +{
> +       size_t umem_sz = DEFAULT_UMEM_BUFFERS * XSK_UMEM__DEFAULT_FRAME_SIZE;
> +       int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
> +       struct xsk_socket_info *xsk;
> +       struct xsk_umem_info *umem;
> +       bool zc_avail = false;
> +       void *bufs;
> +       int ret;
> +
> +       bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
> +       if (bufs == MAP_FAILED)
> +               exit_with_error(errno);
> +
> +       umem = calloc(1, sizeof(struct xsk_umem_info));
> +       if (!umem) {
> +               munmap(bufs, umem_sz);
> +               exit_with_error(-ENOMEM);
> +       }
> +       umem->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
> +       ret = xsk_configure_umem(umem, bufs, umem_sz);
> +       if (ret)
> +               exit_with_error(-ret);
> +
> +       xsk = calloc(1, sizeof(struct xsk_socket_info));
> +       if (!xsk)
> +               goto out;
> +       ifobject->xdp_flags = 0;

This is redundant.

> +       ifobject->xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
> +       ifobject->xdp_flags |= XDP_FLAGS_DRV_MODE;
> +       ifobject->bind_flags = XDP_USE_NEED_WAKEUP | XDP_ZEROCOPY;
> +       ifobject->rx_on = true;
> +       xsk->rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS;
> +       ret = __xsk_configure_socket(xsk, umem, ifobject, false);
> +       if (!ret)
> +               zc_avail = true;
> +
> +       ifobject->xdp_flags = 0;

Why this assignment?

> +       xsk_socket__delete(xsk->xsk);
> +       free(xsk);
> +out:
> +       munmap(umem->buffer, umem_sz);
> +       xsk_umem__delete(umem->umem);
> +       free(umem);
> +       return zc_avail;
> +}
> +
>  static struct option long_options[] = {
>         {"interface", required_argument, 0, 'i'},
>         {"busy-poll", no_argument, 0, 'b'},
> @@ -483,9 +541,14 @@ static void test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
>                 else
>                         ifobj->xdp_flags |= XDP_FLAGS_DRV_MODE;
>
> -               ifobj->bind_flags = XDP_USE_NEED_WAKEUP | XDP_COPY;
> +               ifobj->bind_flags = XDP_USE_NEED_WAKEUP;
> +               if (mode == TEST_MODE_ZC)
> +                       ifobj->bind_flags |= XDP_ZEROCOPY;
> +               else
> +                       ifobj->bind_flags |= XDP_COPY;
>         }
>
> +       test->mode = mode;
>         __test_spec_init(test, ifobj_tx, ifobj_rx);
>  }
>
> @@ -1543,6 +1606,10 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
>  {
>         switch (type) {
>         case TEST_TYPE_STATS_RX_DROPPED:
> +               if (mode == TEST_MODE_ZC) {
> +                       ksft_test_result_skip("Can not run RX_DROPPED test for ZC mode\n");
> +                       return;
> +               }
>                 testapp_stats_rx_dropped(test);
>                 break;
>         case TEST_TYPE_STATS_TX_INVALID_DESCS:
> @@ -1723,8 +1790,11 @@ int main(int argc, char **argv)
>         init_iface(ifobj_rx, MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1,
>                    worker_testapp_validate_rx);
>
> -       if (is_xdp_supported(ifobj_tx))
> -               modes++;
> +       if (is_xdp_supported(ifobj_tx)) {
> +               modes++;
> +               if (ifobj_zc_avail(ifobj_tx))
> +                       modes++;
> +       }
>
>         test_spec_init(&test, ifobj_tx, ifobj_rx, 0);
>         tx_pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, PKT_SIZE);
> diff --git a/tools/testing/selftests/bpf/xdpxceiver.h b/tools/testing/selftests/bpf/xdpxceiver.h
> index 12b792004163..a86331c6b0c5 100644
> --- a/tools/testing/selftests/bpf/xdpxceiver.h
> +++ b/tools/testing/selftests/bpf/xdpxceiver.h
> @@ -61,6 +61,7 @@
>  enum test_mode {
>         TEST_MODE_SKB,
>         TEST_MODE_DRV,
> +       TEST_MODE_ZC,
>         TEST_MODE_MAX
>  };
>
> @@ -162,6 +163,7 @@ struct test_spec {
>         u16 current_step;
>         u16 nb_sockets;
>         bool fail;
> +       enum test_mode mode;
>         char name[MAX_TEST_NAME_SIZE];
>  };
>
> --
> 2.27.0
>



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux