lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAGGp+cGASrZ+e9mYqxO_QRPFFrpuZMxvYD8Ya5jm8E-G1JsOwg@mail.gmail.com>
Date:   Mon, 8 Jul 2019 18:40:28 +0200
From:   Krzesimir Nowak <krzesimir@...volk.io>
To:     linux-kernel@...r.kernel.org
Cc:     Alban Crequy <alban@...volk.io>,
        Iago López Galeiras <iago@...volk.io>,
        Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>,
        Martin KaFai Lau <kafai@...com>,
        Song Liu <songliubraving@...com>, Yonghong Song <yhs@...com>,
        "David S. Miller" <davem@...emloft.net>,
        Jakub Kicinski <jakub.kicinski@...ronome.com>,
        Jesper Dangaard Brouer <hawk@...nel.org>,
        John Fastabend <john.fastabend@...il.com>,
        Stanislav Fomichev <sdf@...gle.com>, netdev@...r.kernel.org,
        bpf@...r.kernel.org, xdp-newbies@...r.kernel.org
Subject: Re: [bpf-next v3 09/12] bpf: Split out some helper functions

On Mon, Jul 8, 2019 at 6:31 PM Krzesimir Nowak <krzesimir@...volk.io> wrote:
>
> The moved functions are generally useful for implementing
> bpf_prog_test_run for other types of BPF programs - they don't have
> any network-specific stuff in them, so I can use them in a test run
> implementation for perf event BPF program too.
>
> Signed-off-by: Krzesimir Nowak <krzesimir@...volk.io>

This patch has some whitespace issues (indentation with spaces instead
of tabs in some places), will fix them for v4. Sorry about that.

> ---
>  include/linux/bpf.h   |  28 +++++
>  kernel/bpf/Makefile   |   1 +
>  kernel/bpf/test_run.c | 212 ++++++++++++++++++++++++++++++++++
>  net/bpf/test_run.c    | 263 +++++++++++-------------------------------
>  4 files changed, 308 insertions(+), 196 deletions(-)
>  create mode 100644 kernel/bpf/test_run.c
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 18f4cc2c6acd..28db8ba57bc3 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1143,4 +1143,32 @@ static inline u32 bpf_xdp_sock_convert_ctx_access(enum bpf_access_type type,
>  }
>  #endif /* CONFIG_INET */
>
> +/* Helper functions for bpf_prog_test_run implementations */
> +typedef u32 bpf_prog_run_helper_t(struct bpf_prog *prog, void *ctx,
> +                                  void *private_data);
> +
> +enum bpf_test_run_flags {
> +       BPF_TEST_RUN_PLAIN = 0,
> +       BPF_TEST_RUN_SETUP_CGROUP_STORAGE = 1 << 0,
> +};
> +
> +int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 flags,
> +                u32 *retval, u32 *duration);
> +
> +int bpf_test_run_cb(struct bpf_prog *prog, void *ctx, u32 repeat, u32 flags,
> +                   bpf_prog_run_helper_t run_prog, void *private_data,
> +                   u32 *retval, u32 *duration);
> +
> +int bpf_test_finish(union bpf_attr __user *uattr, u32 retval, u32 duration);
> +
> +void *bpf_receive_ctx(const union bpf_attr *kattr, u32 max_size);
> +
> +int bpf_send_ctx(const union bpf_attr *kattr, union bpf_attr __user *uattr,
> +                const void *data, u32 size);
> +
> +void *bpf_receive_data(const union bpf_attr *kattr, u32 max_size);
> +
> +int bpf_send_data(const union bpf_attr *kattr, union bpf_attr __user *uattr,
> +                 const void *data, u32 size);
> +
>  #endif /* _LINUX_BPF_H */
> diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
> index 29d781061cd5..570fd40288f4 100644
> --- a/kernel/bpf/Makefile
> +++ b/kernel/bpf/Makefile
> @@ -22,3 +22,4 @@ obj-$(CONFIG_CGROUP_BPF) += cgroup.o
>  ifeq ($(CONFIG_INET),y)
>  obj-$(CONFIG_BPF_SYSCALL) += reuseport_array.o
>  endif
> +obj-$(CONFIG_BPF_SYSCALL) += test_run.o
> diff --git a/kernel/bpf/test_run.c b/kernel/bpf/test_run.c
> new file mode 100644
> index 000000000000..0481373da8be
> --- /dev/null
> +++ b/kernel/bpf/test_run.c
> @@ -0,0 +1,212 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (c) 2017 Facebook
> + * Copyright (c) 2019 Tigera, Inc
> + */
> +
> +#include <asm/div64.h>
> +
> +#include <linux/bpf-cgroup.h>
> +#include <linux/bpf.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/filter.h>
> +#include <linux/gfp.h>
> +#include <linux/kernel.h>
> +#include <linux/limits.h>
> +#include <linux/preempt.h>
> +#include <linux/rcupdate.h>
> +#include <linux/sched.h>
> +#include <linux/sched/signal.h>
> +#include <linux/slab.h>
> +#include <linux/timekeeping.h>
> +#include <linux/uaccess.h>
> +
> +static void teardown_cgroup_storage(struct bpf_cgroup_storage **storage)
> +{
> +       enum bpf_cgroup_storage_type stype;
> +
> +       if (!storage)
> +               return;
> +       for_each_cgroup_storage_type(stype)
> +               bpf_cgroup_storage_free(storage[stype]);
> +       kfree(storage);
> +}
> +
> +static struct bpf_cgroup_storage **setup_cgroup_storage(struct bpf_prog *prog)
> +{
> +       enum bpf_cgroup_storage_type stype;
> +       struct bpf_cgroup_storage **storage;
> +       size_t size = MAX_BPF_CGROUP_STORAGE_TYPE;
> +
> +       size *= sizeof(struct bpf_cgroup_storage *);
> +       storage = kzalloc(size, GFP_KERNEL);
> +       for_each_cgroup_storage_type(stype) {
> +               storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
> +               if (IS_ERR(storage[stype])) {
> +                       storage[stype] = NULL;
> +                       teardown_cgroup_storage(storage);
> +                       return ERR_PTR(-ENOMEM);
> +               }
> +       }
> +       return storage;
> +}
> +
> +static u32 run_bpf_prog(struct bpf_prog *prog, void *ctx, void *private_data)
> +{
> +       return BPF_PROG_RUN(prog, ctx);
> +}
> +
> +int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 flags,
> +                u32 *retval, u32 *duration)
> +{
> +       return bpf_test_run_cb(prog, ctx, repeat, flags, run_bpf_prog, NULL,
> +                              retval, duration);
> +}
> +
> +int bpf_test_run_cb(struct bpf_prog *prog, void *ctx, u32 repeat, u32 flags,
> +                   bpf_prog_run_helper_t run_prog, void *private_data,
> +                   u32 *retval, u32 *duration)
> +{
> +       struct bpf_cgroup_storage **storage = NULL;
> +       u64 time_start, time_spent = 0;
> +       int ret = 0;
> +       u32 i;
> +
> +       if (flags & BPF_TEST_RUN_SETUP_CGROUP_STORAGE) {
> +               storage = setup_cgroup_storage(prog);
> +               if (IS_ERR(storage))
> +                       return PTR_ERR(storage);
> +       }
> +
> +       if (!repeat)
> +               repeat = 1;
> +
> +       rcu_read_lock();
> +       preempt_disable();
> +       time_start = ktime_get_ns();
> +       for (i = 0; i < repeat; i++) {
> +               if (storage)
> +                       bpf_cgroup_storage_set(storage);
> +               *retval = run_prog(prog, ctx, private_data);
> +
> +               if (signal_pending(current)) {
> +                       preempt_enable();
> +                       rcu_read_unlock();
> +                       teardown_cgroup_storage(storage);
> +                       return -EINTR;
> +               }
> +
> +               if (need_resched()) {
> +                       time_spent += ktime_get_ns() - time_start;
> +                       preempt_enable();
> +                       rcu_read_unlock();
> +
> +                       cond_resched();
> +
> +                       rcu_read_lock();
> +                       preempt_disable();
> +                       time_start = ktime_get_ns();
> +               }
> +       }
> +       time_spent += ktime_get_ns() - time_start;
> +       preempt_enable();
> +       rcu_read_unlock();
> +
> +       do_div(time_spent, repeat);
> +       *duration = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
> +
> +       teardown_cgroup_storage(storage);
> +
> +       return ret;
> +}
> +
> +int bpf_test_finish(union bpf_attr __user *uattr, u32 retval, u32 duration)
> +{
> +       if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
> +               return -EFAULT;
> +       if (copy_to_user(&uattr->test.duration, &duration, sizeof(duration)))
> +               return -EFAULT;
> +       return 0;
> +}
> +
> +static void *bpf_receive_mem(u64 in, u32 in_size, u32 max_size)
> +{
> +       void __user *data_in = u64_to_user_ptr(in);
> +       void *data;
> +       int err;
> +
> +       if (!data_in && in_size)
> +               return ERR_PTR(-EINVAL);
> +       data = kzalloc(max_size, GFP_USER);
> +       if (!data)
> +               return ERR_PTR(-ENOMEM);
> +
> +       if (data_in) {
> +               err = bpf_check_uarg_tail_zero(data_in, max_size, in_size);
> +               if (err) {
> +                       kfree(data);
> +                       return ERR_PTR(err);
> +               }
> +
> +               in_size = min_t(u32, max_size, in_size);
> +               if (copy_from_user(data, data_in, in_size)) {
> +                       kfree(data);
> +                       return ERR_PTR(-EFAULT);
> +               }
> +       }
> +       return data;
> +}
> +
> +static int bpf_send_mem(u64 out, u32 out_size, u32 *out_size_write,
> +                        const void *data, u32 data_size)
> +{
> +       void __user *data_out = u64_to_user_ptr(out);
> +       int err = -EFAULT;
> +       u32 copy_size = data_size;
> +
> +       if (!data_out && out_size)
> +               return -EINVAL;
> +
> +       if (!data || !data_out)
> +               return 0;
> +
> +       if (copy_size > out_size) {
> +               copy_size = out_size;
> +               err = -ENOSPC;
> +       }
> +
> +       if (copy_to_user(data_out, data, copy_size))
> +               goto out;
> +       if (copy_to_user(out_size_write, &data_size, sizeof(data_size)))
> +               goto out;
> +       if (err != -ENOSPC)
> +               err = 0;
> +out:
> +       return err;
> +}
> +
> +void *bpf_receive_data(const union bpf_attr *kattr, u32 max_size)
> +{
> +       return bpf_receive_mem(kattr->test.data_in, kattr->test.data_size_in,
> +                               max_size);
> +}
> +
> +int bpf_send_data(const union bpf_attr *kattr, union bpf_attr __user *uattr,
> +                  const void *data, u32 size)
> +{
> +       return bpf_send_mem(kattr->test.data_out, kattr->test.data_size_out,
> +                           &uattr->test.data_size_out, data, size);
> +}
> +
> +void *bpf_receive_ctx(const union bpf_attr *kattr, u32 max_size)
> +{
> +       return bpf_receive_mem(kattr->test.ctx_in, kattr->test.ctx_size_in,
> +                               max_size);
> +}
> +
> +int bpf_send_ctx(const union bpf_attr *kattr, union bpf_attr __user *uattr,
> +                 const void *data, u32 size)
> +{
> +        return bpf_send_mem(kattr->test.ctx_out, kattr->test.ctx_size_out,
> +                            &uattr->test.ctx_size_out, data, size);
> +}
> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> index 80e6f3a6864d..fe6b7b1af0cc 100644
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -14,97 +14,6 @@
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/bpf_test_run.h>
>
> -static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
> -                       u32 *retval, u32 *time)
> -{
> -       struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = { NULL };
> -       enum bpf_cgroup_storage_type stype;
> -       u64 time_start, time_spent = 0;
> -       int ret = 0;
> -       u32 i;
> -
> -       for_each_cgroup_storage_type(stype) {
> -               storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
> -               if (IS_ERR(storage[stype])) {
> -                       storage[stype] = NULL;
> -                       for_each_cgroup_storage_type(stype)
> -                               bpf_cgroup_storage_free(storage[stype]);
> -                       return -ENOMEM;
> -               }
> -       }
> -
> -       if (!repeat)
> -               repeat = 1;
> -
> -       rcu_read_lock();
> -       preempt_disable();
> -       time_start = ktime_get_ns();
> -       for (i = 0; i < repeat; i++) {
> -               bpf_cgroup_storage_set(storage);
> -               *retval = BPF_PROG_RUN(prog, ctx);
> -
> -               if (signal_pending(current)) {
> -                       ret = -EINTR;
> -                       break;
> -               }
> -
> -               if (need_resched()) {
> -                       time_spent += ktime_get_ns() - time_start;
> -                       preempt_enable();
> -                       rcu_read_unlock();
> -
> -                       cond_resched();
> -
> -                       rcu_read_lock();
> -                       preempt_disable();
> -                       time_start = ktime_get_ns();
> -               }
> -       }
> -       time_spent += ktime_get_ns() - time_start;
> -       preempt_enable();
> -       rcu_read_unlock();
> -
> -       do_div(time_spent, repeat);
> -       *time = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
> -
> -       for_each_cgroup_storage_type(stype)
> -               bpf_cgroup_storage_free(storage[stype]);
> -
> -       return ret;
> -}
> -
> -static int bpf_test_finish(const union bpf_attr *kattr,
> -                          union bpf_attr __user *uattr, const void *data,
> -                          u32 size, u32 retval, u32 duration)
> -{
> -       void __user *data_out = u64_to_user_ptr(kattr->test.data_out);
> -       int err = -EFAULT;
> -       u32 copy_size = size;
> -
> -       /* Clamp copy if the user has provided a size hint, but copy the full
> -        * buffer if not to retain old behaviour.
> -        */
> -       if (kattr->test.data_size_out &&
> -           copy_size > kattr->test.data_size_out) {
> -               copy_size = kattr->test.data_size_out;
> -               err = -ENOSPC;
> -       }
> -
> -       if (data_out && copy_to_user(data_out, data, copy_size))
> -               goto out;
> -       if (copy_to_user(&uattr->test.data_size_out, &size, sizeof(size)))
> -               goto out;
> -       if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
> -               goto out;
> -       if (copy_to_user(&uattr->test.duration, &duration, sizeof(duration)))
> -               goto out;
> -       if (err != -ENOSPC)
> -               err = 0;
> -out:
> -       trace_bpf_test_finish(&err);
> -       return err;
> -}
> -
>  static void *bpf_test_init(const union bpf_attr *kattr, u32 size,
>                            u32 headroom, u32 tailroom)
>  {
> @@ -125,63 +34,6 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 size,
>         return data;
>  }
>
> -static void *bpf_ctx_init(const union bpf_attr *kattr, u32 max_size)
> -{
> -       void __user *data_in = u64_to_user_ptr(kattr->test.ctx_in);
> -       void __user *data_out = u64_to_user_ptr(kattr->test.ctx_out);
> -       u32 size = kattr->test.ctx_size_in;
> -       void *data;
> -       int err;
> -
> -       if (!data_in && !data_out)
> -               return NULL;
> -
> -       data = kzalloc(max_size, GFP_USER);
> -       if (!data)
> -               return ERR_PTR(-ENOMEM);
> -
> -       if (data_in) {
> -               err = bpf_check_uarg_tail_zero(data_in, max_size, size);
> -               if (err) {
> -                       kfree(data);
> -                       return ERR_PTR(err);
> -               }
> -
> -               size = min_t(u32, max_size, size);
> -               if (copy_from_user(data, data_in, size)) {
> -                       kfree(data);
> -                       return ERR_PTR(-EFAULT);
> -               }
> -       }
> -       return data;
> -}
> -
> -static int bpf_ctx_finish(const union bpf_attr *kattr,
> -                         union bpf_attr __user *uattr, const void *data,
> -                         u32 size)
> -{
> -       void __user *data_out = u64_to_user_ptr(kattr->test.ctx_out);
> -       int err = -EFAULT;
> -       u32 copy_size = size;
> -
> -       if (!data || !data_out)
> -               return 0;
> -
> -       if (copy_size > kattr->test.ctx_size_out) {
> -               copy_size = kattr->test.ctx_size_out;
> -               err = -ENOSPC;
> -       }
> -
> -       if (copy_to_user(data_out, data, copy_size))
> -               goto out;
> -       if (copy_to_user(&uattr->test.ctx_size_out, &size, sizeof(size)))
> -               goto out;
> -       if (err != -ENOSPC)
> -               err = 0;
> -out:
> -       return err;
> -}
> -
>  /**
>   * range_is_zero - test whether buffer is initialized
>   * @buf: buffer to check
> @@ -238,6 +90,36 @@ static void convert_skb_to___skb(struct sk_buff *skb, struct __sk_buff *__skb)
>         memcpy(__skb->cb, &cb->data, QDISC_CB_PRIV_LEN);
>  }
>
> +static int bpf_net_prog_test_run_finish(const union bpf_attr *kattr,
> +                                        union bpf_attr __user *uattr,
> +                                        const void *data, u32 data_size,
> +                                        const void *ctx, u32 ctx_size,
> +                                        u32 retval, u32 duration)
> +{
> +       int ret;
> +       union bpf_attr fixed_kattr;
> +       const union bpf_attr *kattr_ptr = kattr;
> +
> +       /* Clamp copy (in bpf_send_mem) if the user has provided a
> +        * size hint, but copy the full buffer if not to retain old
> +        * behaviour.
> +        */
> +       if (!kattr->test.data_size_out && kattr->test.data_out) {
> +               fixed_kattr = *kattr;
> +               fixed_kattr.test.data_size_out = U32_MAX;
> +               kattr_ptr = &fixed_kattr;
> +       }
> +
> +       ret = bpf_send_data(kattr_ptr, uattr, data, data_size);
> +       if (!ret) {
> +               ret = bpf_test_finish(uattr, retval, duration);
> +               if (!ret && ctx)
> +                       ret = bpf_send_ctx(kattr_ptr, uattr, ctx, ctx_size);
> +       }
> +       trace_bpf_test_finish(&ret);
> +       return ret;
> +}
> +
>  int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
>                           union bpf_attr __user *uattr)
>  {
> @@ -257,7 +139,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
>         if (IS_ERR(data))
>                 return PTR_ERR(data);
>
> -       ctx = bpf_ctx_init(kattr, sizeof(struct __sk_buff));
> +       ctx = bpf_receive_ctx(kattr, sizeof(struct __sk_buff));
>         if (IS_ERR(ctx)) {
>                 kfree(data);
>                 return PTR_ERR(ctx);
> @@ -307,7 +189,8 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
>         ret = convert___skb_to_skb(skb, ctx);
>         if (ret)
>                 goto out;
> -       ret = bpf_test_run(prog, skb, repeat, &retval, &duration);
> +       ret = bpf_test_run(prog, skb, repeat, BPF_TEST_RUN_SETUP_CGROUP_STORAGE,
> +                          &retval, &duration);
>         if (ret)
>                 goto out;
>         if (!is_l2) {
> @@ -327,10 +210,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
>         /* bpf program can never convert linear skb to non-linear */
>         if (WARN_ON_ONCE(skb_is_nonlinear(skb)))
>                 size = skb_headlen(skb);
> -       ret = bpf_test_finish(kattr, uattr, skb->data, size, retval, duration);
> -       if (!ret)
> -               ret = bpf_ctx_finish(kattr, uattr, ctx,
> -                                    sizeof(struct __sk_buff));
> +       ret = bpf_net_prog_test_run_finish(kattr, uattr, skb->data, size,
> +                                          ctx, sizeof(struct __sk_buff),
> +                                          retval, duration);
>  out:
>         kfree_skb(skb);
>         bpf_sk_storage_free(sk);
> @@ -365,32 +247,48 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
>         rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
>         xdp.rxq = &rxqueue->xdp_rxq;
>
> -       ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration);
> +       ret = bpf_test_run(prog, &xdp, repeat,
> +                          BPF_TEST_RUN_SETUP_CGROUP_STORAGE,
> +                          &retval, &duration);
>         if (ret)
>                 goto out;
>         if (xdp.data != data + XDP_PACKET_HEADROOM + NET_IP_ALIGN ||
>             xdp.data_end != xdp.data + size)
>                 size = xdp.data_end - xdp.data;
> -       ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration);
> +       ret = bpf_net_prog_test_run_finish(kattr, uattr, xdp.data, size,
> +                                          NULL, 0, retval, duration);
>  out:
>         kfree(data);
>         return ret;
>  }
>
> +struct bpf_flow_dissect_run_data {
> +       __be16 proto;
> +       int nhoff;
> +       int hlen;
> +};
> +
> +static u32 bpf_flow_dissect_run(struct bpf_prog *prog, void *ctx,
> +                               void *private_data)
> +{
> +       struct bpf_flow_dissect_run_data *data = private_data;
> +
> +       return bpf_flow_dissect(prog, ctx, data->proto, data->nhoff, data->hlen);
> +}
> +
>  int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
>                                      const union bpf_attr *kattr,
>                                      union bpf_attr __user *uattr)
>  {
> +       struct bpf_flow_dissect_run_data run_data = {};
>         u32 size = kattr->test.data_size_in;
>         struct bpf_flow_dissector ctx = {};
>         u32 repeat = kattr->test.repeat;
>         struct bpf_flow_keys flow_keys;
> -       u64 time_start, time_spent = 0;
>         const struct ethhdr *eth;
>         u32 retval, duration;
>         void *data;
>         int ret;
> -       u32 i;
>
>         if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR)
>                 return -EINVAL;
> @@ -407,49 +305,22 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
>
>         eth = (struct ethhdr *)data;
>
> -       if (!repeat)
> -               repeat = 1;
> -
>         ctx.flow_keys = &flow_keys;
>         ctx.data = data;
>         ctx.data_end = (__u8 *)data + size;
>
> -       rcu_read_lock();
> -       preempt_disable();
> -       time_start = ktime_get_ns();
> -       for (i = 0; i < repeat; i++) {
> -               retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
> -                                         size);
> -
> -               if (signal_pending(current)) {
> -                       preempt_enable();
> -                       rcu_read_unlock();
> -
> -                       ret = -EINTR;
> -                       goto out;
> -               }
> -
> -               if (need_resched()) {
> -                       time_spent += ktime_get_ns() - time_start;
> -                       preempt_enable();
> -                       rcu_read_unlock();
> -
> -                       cond_resched();
> -
> -                       rcu_read_lock();
> -                       preempt_disable();
> -                       time_start = ktime_get_ns();
> -               }
> -       }
> -       time_spent += ktime_get_ns() - time_start;
> -       preempt_enable();
> -       rcu_read_unlock();
> -
> -       do_div(time_spent, repeat);
> -       duration = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
> +       run_data.proto = eth->h_proto;
> +       run_data.nhoff = ETH_HLEN;
> +       run_data.hlen = size;
> +       ret = bpf_test_run_cb(prog, &ctx, repeat, BPF_TEST_RUN_PLAIN,
> +                             bpf_flow_dissect_run, &run_data,
> +                             &retval, &duration);
> +       if (!ret)
> +               goto out;
>
> -       ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys),
> -                             retval, duration);
> +       ret = bpf_net_prog_test_run_finish(kattr, uattr, &flow_keys,
> +                                          sizeof(flow_keys), NULL, 0,
> +                                          retval, duration);
>
>  out:
>         kfree(data);
> --
> 2.20.1
>


-- 
Kinvolk GmbH | Adalbertstr.6a, 10999 Berlin | tel: +491755589364
Geschäftsführer/Directors: Alban Crequy, Chris Kühl, Iago López Galeiras
Registergericht/Court of registration: Amtsgericht Charlottenburg
Registernummer/Registration number: HRB 171414 B
Ust-ID-Nummer/VAT ID number: DE302207000

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ