bpf: pass a struct with offload callbacks to bpf_offload_dev_create()
authorQuentin Monnet <quentin.monnet@netronome.com>
Fri, 9 Nov 2018 13:03:25 +0000 (13:03 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 10 Nov 2018 23:39:53 +0000 (15:39 -0800)
For passing device functions for offloaded eBPF programs, there used to
be no place where to store the pointer without making the non-offloaded
programs pay a memory price.

As a consequence, three functions were called with ndo_bpf() through
specific commands. Now that we have struct bpf_offload_dev, and since
none of those operations rely on RTNL, we can turn these three commands
into hooks inside the struct bpf_prog_offload_ops, and pass them as part
of bpf_offload_dev_create().

This commit effectively passes a pointer to the struct to
bpf_offload_dev_create(). We temporarily have two struct
bpf_prog_offload_ops instances, one under offdev->ops and one under
offload->dev_ops. The next patches will make the transition towards the
former, so that offload->dev_ops can be removed, and callbacks relying
on ndo_bpf() added to offdev->ops as well.

While at it, rename "nfp_bpf_analyzer_ops" as "nfp_bpf_dev_ops" (and
similarly for netdevsim).

Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
drivers/net/ethernet/netronome/nfp/bpf/main.c
drivers/net/ethernet/netronome/nfp/bpf/main.h
drivers/net/ethernet/netronome/nfp/bpf/offload.c
drivers/net/netdevsim/bpf.c
include/linux/bpf.h
kernel/bpf/offload.c

index 6243af0ab02558811ccb494d2a10d4044cde9257..dccae03192045f302091a92945e4e09047c62125 100644 (file)
@@ -465,7 +465,7 @@ static int nfp_bpf_init(struct nfp_app *app)
                app->ctrl_mtu = nfp_bpf_ctrl_cmsg_mtu(bpf);
        }
 
-       bpf->bpf_dev = bpf_offload_dev_create();
+       bpf->bpf_dev = bpf_offload_dev_create(&nfp_bpf_dev_ops);
        err = PTR_ERR_OR_ZERO(bpf->bpf_dev);
        if (err)
                goto err_free_neutral_maps;
index abdd93d14439652c2c57c52ff6674ea950229700..941277936475c661ca12028a7929b9f2fb9fbd10 100644 (file)
@@ -513,7 +513,7 @@ int nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx,
                    int prev_insn_idx);
 int nfp_bpf_finalize(struct bpf_verifier_env *env);
 
-extern const struct bpf_prog_offload_ops nfp_bpf_analyzer_ops;
+extern const struct bpf_prog_offload_ops nfp_bpf_dev_ops;
 
 struct netdev_bpf;
 struct nfp_app;
index dc548bb4089e229beb971a446fd24d50dca55f1e..2fca996a7e775bc77999ca6faaf0ac0b9d089ad6 100644 (file)
@@ -209,7 +209,7 @@ nfp_bpf_verifier_prep(struct nfp_app *app, struct nfp_net *nn,
                goto err_free;
 
        nfp_prog->verifier_meta = nfp_prog_first_meta(nfp_prog);
-       bpf->verifier.ops = &nfp_bpf_analyzer_ops;
+       bpf->verifier.ops = &nfp_bpf_dev_ops;
 
        return 0;
 
@@ -602,7 +602,7 @@ int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog,
        return 0;
 }
 
-const struct bpf_prog_offload_ops nfp_bpf_analyzer_ops = {
+const struct bpf_prog_offload_ops nfp_bpf_dev_ops = {
        .insn_hook      = nfp_verify_insn,
        .finalize       = nfp_bpf_finalize,
 };
index cb3518474f0e4248967b5c5710c3137288cf23d7..135aee8641628554411250b97119b6041fd5c329 100644 (file)
@@ -91,7 +91,7 @@ static int nsim_bpf_finalize(struct bpf_verifier_env *env)
        return 0;
 }
 
-static const struct bpf_prog_offload_ops nsim_bpf_analyzer_ops = {
+static const struct bpf_prog_offload_ops nsim_bpf_dev_ops = {
        .insn_hook      = nsim_bpf_verify_insn,
        .finalize       = nsim_bpf_finalize,
 };
@@ -547,7 +547,7 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
                if (err)
                        return err;
 
-               bpf->verifier.ops = &nsim_bpf_analyzer_ops;
+               bpf->verifier.ops = &nsim_bpf_dev_ops;
                return 0;
        case BPF_OFFLOAD_TRANSLATE:
                state = bpf->offload.prog->aux->offload->dev_priv;
@@ -599,7 +599,7 @@ int nsim_bpf_init(struct netdevsim *ns)
                if (IS_ERR_OR_NULL(ns->sdev->ddir_bpf_bound_progs))
                        return -ENOMEM;
 
-               ns->sdev->bpf_dev = bpf_offload_dev_create();
+               ns->sdev->bpf_dev = bpf_offload_dev_create(&nsim_bpf_dev_ops);
                err = PTR_ERR_OR_ZERO(ns->sdev->bpf_dev);
                if (err)
                        return err;
index b6a296e01f6a9b17d8851484c4ac6e95c4e44fe8..c0197c37b2b2d66d2aa8023bdeffc99d84f727fe 100644 (file)
@@ -692,7 +692,8 @@ int bpf_map_offload_get_next_key(struct bpf_map *map,
 
 bool bpf_offload_prog_map_match(struct bpf_prog *prog, struct bpf_map *map);
 
-struct bpf_offload_dev *bpf_offload_dev_create(void);
+struct bpf_offload_dev *
+bpf_offload_dev_create(const struct bpf_prog_offload_ops *ops);
 void bpf_offload_dev_destroy(struct bpf_offload_dev *offdev);
 int bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,
                                    struct net_device *netdev);
index 8e93c47f0779617c7fca6158170f1b66dc100d66..d513fbf9ca5313bf2d4d7b89090f37757217cf12 100644 (file)
@@ -33,6 +33,7 @@
 static DECLARE_RWSEM(bpf_devs_lock);
 
 struct bpf_offload_dev {
+       const struct bpf_prog_offload_ops *ops;
        struct list_head netdevs;
 };
 
@@ -655,7 +656,8 @@ unlock:
 }
 EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_unregister);
 
-struct bpf_offload_dev *bpf_offload_dev_create(void)
+struct bpf_offload_dev *
+bpf_offload_dev_create(const struct bpf_prog_offload_ops *ops)
 {
        struct bpf_offload_dev *offdev;
        int err;
@@ -673,6 +675,7 @@ struct bpf_offload_dev *bpf_offload_dev_create(void)
        if (!offdev)
                return ERR_PTR(-ENOMEM);
 
+       offdev->ops = ops;
        INIT_LIST_HEAD(&offdev->netdevs);
 
        return offdev;