From: Jakub Kicinski <jakub.kicinski@netronome.com>
To: alexei.starovoitov@gmail.com, daniel@iogearbox.net, davem@davemloft.net
Cc: netdev@vger.kernel.org, oss-drivers@netronome.com,
tehnerd@fb.com, Jakub Kicinski <jakub.kicinski@netronome.com>
Subject: [PATCH bpf-next v2 15/15] nfp: bpf: implement bpf map offload
Date: Thu, 11 Jan 2018 20:29:17 -0800 [thread overview]
Message-ID: <20180112042917.10348-16-jakub.kicinski@netronome.com> (raw)
In-Reply-To: <20180112042917.10348-1-jakub.kicinski@netronome.com>
Plug in to the stack's map offload callbacks for BPF map offload.
Get next call needs some special handling on the FW side, since
we can't send a NULL pointer to the FW there is a get first entry
FW command.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
drivers/net/ethernet/netronome/nfp/bpf/main.c | 1 +
drivers/net/ethernet/netronome/nfp/bpf/main.h | 4 +
drivers/net/ethernet/netronome/nfp/bpf/offload.c | 104 +++++++++++++++++++++++
3 files changed, 109 insertions(+)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index 7d5cc59feb7e..8823c8360047 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -381,6 +381,7 @@ static void nfp_bpf_clean(struct nfp_app *app)
WARN_ON(!skb_queue_empty(&bpf->cmsg_replies));
WARN_ON(!list_empty(&bpf->map_list));
+ WARN_ON(bpf->maps_in_use || bpf->map_elems_in_use);
kfree(bpf);
}
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index 59197535c465..b80e75a8ecda 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -108,6 +108,8 @@ enum pkt_vec {
* @cmsg_wq: work queue for waiting for cmsg replies
*
* @map_list: list of offloaded maps
+ * @maps_in_use: number of currently offloaded maps
+ * @map_elems_in_use: number of elements allocated to offloaded maps
*
* @adjust_head: adjust head capability
* @flags: extra flags for adjust head
@@ -138,6 +140,8 @@ struct nfp_app_bpf {
struct wait_queue_head cmsg_wq;
struct list_head map_list;
+ unsigned int maps_in_use;
+ unsigned int map_elems_in_use;
struct nfp_bpf_cap_adjust_head {
u32 flags;
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 6590228d3755..e2859b2e9c6a 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -36,6 +36,9 @@
* Netronome network device driver: TC offload functions for PF and VF
*/
+#define pr_fmt(fmt) "NFP net bpf: " fmt
+
+#include <linux/bpf.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
@@ -153,6 +156,103 @@ static int nfp_bpf_destroy(struct nfp_net *nn, struct bpf_prog *prog)
return 0;
}
+static int
+nfp_bpf_map_get_next_key(struct bpf_offloaded_map *offmap,
+ void *key, void *next_key)
+{
+ if (!key)
+ return nfp_bpf_ctrl_getfirst_entry(offmap, next_key);
+ return nfp_bpf_ctrl_getnext_entry(offmap, key, next_key);
+}
+
+static int
+nfp_bpf_map_delete_elem(struct bpf_offloaded_map *offmap, void *key)
+{
+ return nfp_bpf_ctrl_del_entry(offmap, key);
+}
+
+static const struct bpf_map_dev_ops nfp_bpf_map_ops = {
+ .map_get_next_key = nfp_bpf_map_get_next_key,
+ .map_lookup_elem = nfp_bpf_ctrl_lookup_entry,
+ .map_update_elem = nfp_bpf_ctrl_update_entry,
+ .map_delete_elem = nfp_bpf_map_delete_elem,
+};
+
+static int
+nfp_bpf_map_alloc(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap)
+{
+ struct nfp_bpf_map *nfp_map;
+ long long int res;
+
+ if (!bpf->maps.types)
+ return -EOPNOTSUPP;
+
+ if (offmap->map.map_flags ||
+ offmap->map.numa_node != NUMA_NO_NODE) {
+ pr_info("map flags are not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(bpf->maps.types & 1 << offmap->map.map_type)) {
+ pr_info("map type not supported\n");
+ return -EOPNOTSUPP;
+ }
+ if (bpf->maps.max_maps == bpf->maps_in_use) {
+ pr_info("too many maps for a device\n");
+ return -ENOMEM;
+ }
+ if (bpf->maps.max_elems - bpf->map_elems_in_use <
+ offmap->map.max_entries) {
+ pr_info("map with too many elements: %u, left: %u\n",
+ offmap->map.max_entries,
+ bpf->maps.max_elems - bpf->map_elems_in_use);
+ return -ENOMEM;
+ }
+ if (offmap->map.key_size > bpf->maps.max_key_sz ||
+ offmap->map.value_size > bpf->maps.max_val_sz ||
+ round_up(offmap->map.key_size, 8) +
+ round_up(offmap->map.value_size, 8) > bpf->maps.max_elem_sz) {
+ pr_info("elements don't fit in device constraints\n");
+ return -ENOMEM;
+ }
+
+ nfp_map = kzalloc(sizeof(*nfp_map), GFP_USER);
+ if (!nfp_map)
+ return -ENOMEM;
+
+ offmap->dev_priv = nfp_map;
+ nfp_map->offmap = offmap;
+ nfp_map->bpf = bpf;
+
+ res = nfp_bpf_ctrl_alloc_map(bpf, &offmap->map);
+ if (res < 0) {
+ kfree(nfp_map);
+ return res;
+ }
+
+ nfp_map->tid = res;
+ offmap->dev_ops = &nfp_bpf_map_ops;
+ bpf->maps_in_use++;
+ bpf->map_elems_in_use += offmap->map.max_entries;
+ list_add_tail(&nfp_map->l, &bpf->map_list);
+
+ return 0;
+}
+
+static int
+nfp_bpf_map_free(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap)
+{
+ struct nfp_bpf_map *nfp_map = offmap->dev_priv;
+
+ nfp_bpf_ctrl_free_map(bpf, nfp_map);
+ list_del_init(&nfp_map->l);
+ bpf->map_elems_in_use -= offmap->map.max_entries;
+ bpf->maps_in_use--;
+ kfree(nfp_map);
+
+ return 0;
+}
+
int nfp_ndo_bpf(struct nfp_app *app, struct nfp_net *nn, struct netdev_bpf *bpf)
{
switch (bpf->command) {
@@ -162,6 +262,10 @@ int nfp_ndo_bpf(struct nfp_app *app, struct nfp_net *nn, struct netdev_bpf *bpf)
return nfp_bpf_translate(nn, bpf->offload.prog);
case BPF_OFFLOAD_DESTROY:
return nfp_bpf_destroy(nn, bpf->offload.prog);
+ case BPF_OFFLOAD_MAP_ALLOC:
+ return nfp_bpf_map_alloc(app->priv, bpf->offmap);
+ case BPF_OFFLOAD_MAP_FREE:
+ return nfp_bpf_map_free(app->priv, bpf->offmap);
default:
return -EINVAL;
}
--
2.15.1
next prev parent reply other threads:[~2018-01-12 4:29 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-12 4:29 [PATCH bpf-next v2 00/15] bpf: support creating maps on networking devices Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 01/15] bpf: add map_alloc_check callback Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 02/15] bpf: hashtab: move attribute validation before allocation Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 03/15] bpf: hashtab: move checks out of alloc function Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 04/15] bpf: add helper for copying attrs to struct bpf_map Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 05/15] bpf: rename bpf_dev_offload -> bpf_prog_offload Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 06/15] bpf: offload: factor out netdev checking at allocation time Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 07/15] bpf: offload: add map offload infrastructure Jakub Kicinski
2018-01-14 23:37 ` Daniel Borkmann
2018-01-14 23:52 ` Jakub Kicinski
2018-01-14 23:58 ` Daniel Borkmann
2018-01-12 4:29 ` [PATCH bpf-next v2 08/15] nfp: bpf: add map data structure Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 09/15] nfp: bpf: add basic control channel communication Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 10/15] nfp: bpf: implement helpers for FW map ops Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 11/15] nfp: bpf: parse function call and map capabilities Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 12/15] nfp: bpf: add helpers for updating immediate instructions Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 13/15] nfp: bpf: add verification and codegen for map lookups Jakub Kicinski
2018-01-12 4:29 ` [PATCH bpf-next v2 14/15] nfp: bpf: add support for reading map memory Jakub Kicinski
2018-01-12 4:29 ` Jakub Kicinski [this message]
2018-01-15 0:00 ` [PATCH bpf-next v2 00/15] bpf: support creating maps on networking devices Daniel Borkmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180112042917.10348-16-jakub.kicinski@netronome.com \
--to=jakub.kicinski@netronome.com \
--cc=alexei.starovoitov@gmail.com \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=oss-drivers@netronome.com \
--cc=tehnerd@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).